โš™๏ธ CS & ๊ธฐํƒ€ ๊ฐœ๋ฐœ ์ž๋ฃŒ

[OS] ๋ฉ€ํ‹ฐ์Šค๋ ˆ๋“œ์—์„œ ๊ฒฝ์Ÿ ์ƒํƒœ ํ•ด๊ฒฐ: ์ƒํ˜ธ ๋ฐฐ์ œ (๋ฎคํ…์Šค์™€ ์„ธ๋งˆํฌ์–ด)

์†Œ์˜ ๐Ÿ€ 2025. 6. 2. 01:34
๐Ÿ“Œ ์˜ค๋Š˜ ์ฃผ์ œ์ธ ๊ฒฝ์Ÿ ์ƒํƒœ์™€ ์ƒํ˜ธ ๋ฐฐ์ œ๋Š” ๋ฉ€ํ‹ฐ์Šค๋ ˆ๋“œ ์™ธ์—๋„ ๋ฉ€ํ‹ฐํ”„๋กœ์„ธ์Šค์—์„œ๋„ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋Š” ๋ฌธ์ œ์ด์ง€๋งŒ
์ œ๊ฐ€ ๋ฉ€ํ‹ฐ์Šค๋ ˆ๋“œ์— ๋Œ€ํ•ด ๋ฐฐ์šฐ๋ฉฐ ์ •๋ฆฌํ•œ ๋‚ด์šฉ์œผ๋กœ, ๋ฉ€ํ‹ฐ์Šค๋ ˆ๋“œ์— ๋Œ€ํ•ด์„œ๋งŒ ์ค‘์ ์ ์œผ๋กœ ์–ธ๊ธ‰ํ–ˆ์Šต๋‹ˆ๋‹ค.
์ฐฉ์˜ค๊ฐ€ ์—†์œผ์‹œ๊ธธ!

โœ… ๋ฉ€ํ‹ฐ์Šค๋ ˆ๋“œ๋ž€?

์ด์ „ ๊ธ€์—์„œ ์Šค๋ ˆ๋“œ์˜ ๊ฐœ๋…์„ ์‚ดํŽด๋ดค์Šต๋‹ˆ๋‹ค.

 

โš™๏ธ ํ”„๋กœ์„ธ์Šค / ์Šค๋ ˆ๋“œ ๊ฐœ๋… ์ •๋ฆฌ

๐Ÿ“Œ ์š”์•ฝํ”„๋กœ๊ทธ๋žจ: ์–ด๋А ์ž‘์—…์„ ํ•˜๊ธฐ ์œ„ํ•ด ์‹คํ–‰๋  ์ˆ˜ ์žˆ๋Š” ํŒŒ์ผํ”„๋กœ์„ธ์Šค: ๋ฉ”๋ชจ๋ฆฌ์— ์˜ฌ๋ผ๊ฐ€๊ณ , ์šด์˜์ฒด์ œ๋กœ๋ถ€ํ„ฐ CPU๋ฅผ ํ• ๋‹น๋ฐ›์•„ ์‹คํ–‰ ์ค‘์ธ ํ”„๋กœ๊ทธ๋žจ์Šค๋ ˆ๋“œ: ํ”„๋กœ์„ธ์Šค ๋‚ด์—์„œ ๋…๋ฆฝ์ ์œผ๋กœ ์‹คํ–‰๋˜๋Š”

syleeblog.tistory.com

 

๋ฉ€ํ‹ฐ์Šค๋ ˆ๋“œ๋ž€ ํ•˜๋‚˜์˜ ํ”„๋กœ์„ธ์Šค ์•ˆ์— ์—ฌ๋Ÿฌ ๊ฐœ์˜ ์Šค๋ ˆ๋“œ๊ฐ€ ์žˆ๋Š” ์ƒํƒœ๋ฅผ ๋งํ•ฉ๋‹ˆ๋‹ค.

์ฆ‰, ํ•˜๋‚˜์˜ ํ”„๋กœ์„ธ์Šค ์•ˆ์—์„œ ๋‘ ๊ฐ€์ง€ ์ด์ƒ์˜ ์ž‘์—…์„ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

 

ํฌ๋กฌ์—์„œ ์—ฌ๋Ÿฌ ์ฐฝ์„ ๋„์›Œ ๊ฐ์ž ์ž‘์—…ํ•  ์ˆ˜ ์žˆ๋“ฏ์ด

๋ฉ€ํ‹ฐ์Šค๋ ˆ๋“œ ํ™˜๊ฒฝ์—์„œ๋Š” ์—ฌ๋Ÿฌ ์ž‘์—…์„ ๋™์‹œ์—, ๋…๋ฆฝ์ ์œผ๋กœ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ์žฅ์ ์ด ์žˆ์Šต๋‹ˆ๋‹ค.

์˜ˆ๋ฅผ ๋“ค์–ด, ์นด์นด์˜คํ†ก์—์„œ ํŒŒ์ผ์„ ์ „์†กํ•˜๋Š” ๋ฐ ๋ช‡ ์ดˆ๊ฐ€ ๊ฑธ๋ฆฌ๊ธฐ๋„ ํ•˜์ง€๋งŒ, ๊ทธ ์‹œ๊ฐ„ ๋™์•ˆ ์‚ฌ์šฉ์ž๋Š” ์ „์†ก์ด ๋๋‚˜๊ธฐ๋ฅผ ๊ธฐ๋‹ค๋ฆฌ๋Š” ๊ฒŒ ์•„๋‹ˆ๋ผ ์ƒˆ๋กœ์šด ํ†ก์„ ๋ณด๋‚ด๋Š” ๋“ฑ์˜ ๋‹ค๋ฅธ ํ–‰๋™์„ ์ž์œ ๋กญ๊ฒŒ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

๋˜ํ•œ ์„œ๋กœ ๋ณ„๊ฐœ์˜ ๋ฉ”๋ชจ๋ฆฌ ๊ณต๊ฐ„์„ ๊ฐ€์ง€๋Š” ํ”„๋กœ์„ธ์Šค์™€ ๋‹ฌ๋ฆฌ

์Šค๋ ˆ๋“œ๋ผ๋ฆฌ๋Š” ํ”„๋กœ์„ธ์Šค ๋‚ด ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ์ผ๋ถ€ ๊ณต์œ ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋ฉ€ํ‹ฐ ํ”„๋กœ์„ธ์Šค์— ๋น„ํ•ด ์ž์›๊ณผ ๊ณต๊ฐ„์ด ์ ˆ์•ฝ๋˜๋Š” ํšจ๊ณผ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

 

๊ทธ๋Ÿฌ๋‚˜ ๋™์‹œ์— ์ ‘๊ทผํ•˜๊ณ  ์‹คํ–‰๋˜๋Š” ํ๋ฆ„์ด ๋งŽ๋‹ค๋Š” ๊ฒƒ์€ ๊ณต์œ  ์ž์›์„ ๋‘˜๋Ÿฌ์‹ผ ๋ฌธ์ œ์˜ ๊ฐ€๋Šฅ์„ฑ๋„ ์ปค์ง„๋‹ค๋Š” ๋œป์ด๊ธฐ๋„ ํ•ฉ๋‹ˆ๋‹ค.

๊ทธ ๋Œ€ํ‘œ์ ์ธ ๋ฌธ์ œ๋กœ ๊ต์ฐฉ ์ƒํƒœ(Deadlock), ๊ธฐ์•„ ์ƒํƒœ(Starvation), ๊ฒฝ์Ÿ ์ƒํƒœ(Race Condition) ๋“ฑ์ด ์žˆ๋Š”๋ฐ

์ด ๊ธ€์—์„œ๋Š” ๊ฒฝ์Ÿ ์ƒํƒœ(Race Condition)์— ๋Œ€ํ•ด ์ž์„ธํžˆ ๋‹ค๋ค„๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

 


๐Ÿš€ ๊ฒฝ์Ÿ ์ƒํƒœ (Race Condition)

๊ฒฝ์Ÿ ์ƒํƒœ๋ž€ ๋‘˜ ์ด์ƒ์˜ ์Šค๋ ˆ๋“œ๊ฐ€ ๊ณต์œ ๋œ ์ž์›์— ๋Œ€ํ•ด ๋™์‹œ์— ์ ‘๊ทผํ•˜๋ฉด์„œ ์‹คํ–‰ ์ˆœ์„œ์— ๋”ฐ๋ผ ๊ฒฐ๊ณผ๊ฐ€ ๋‹ฌ๋ผ์ง€๋Š” ๋ฌธ์ œ๋ฅผ ๋งํ•ฉ๋‹ˆ๋‹ค.

 

์˜ˆ๋ฅผ ๋“ค์–ด ๋ณผ๊นŒ์š”?

public class Counter {
    private int count = 0;

    public void increment() {
        count++;
    }

    public int getCount() {
        return count;
    }
}

 

์œ„์˜ increment() ๋ฉ”์„œ๋“œ๋Š” ๋‹จ์ˆœํžˆ count๋ฅผ 1 ์ฆ๊ฐ€์‹œํ‚ค๋Š” ์ฝ”๋“œ์ž…๋‹ˆ๋‹ค.

์—ฌ๋Ÿฌ ์Šค๋ ˆ๋“œ๊ฐ€ ๋™์‹œ์— ์ด ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด ์–ด๋–ป๊ฒŒ ๋ ๊นŒ์š”?

 

Thread t1 = new Thread(() -> {
    for (int i = 0; i < 1000; i++) {
        counter.increment();
    }
});

Thread t2 = new Thread(() -> {
    for (int i = 0; i < 1000; i++) {
        counter.increment();
    }
});

 

๋‘ ๊ฐœ์˜ ์Šค๋ ˆ๋“œ์—์„œ ๊ฐ๊ฐ 1000๋ฒˆ์”ฉ ์ฆ๊ฐ€์‹œ์ผฐ๋Š”๋ฐ

๊ฒฐ๊ณผ๊ฐ€ 2000๋ณด๋‹ค ์ž‘์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

๋ฌธ์ œ๋Š” count++์ด๋ž€ ๋™์ž‘์ด ์‚ฌ์‹ค ์„ธ ๊ฐœ์˜ ๋™์ž‘์œผ๋กœ ๋‚˜๋‰˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.

  1. count ๊ฐ’์„ ์ฝ๋Š”๋‹ค
  2. 1์„ ๋”ํ•œ๋‹ค
  3. ๊ฒฐ๊ณผ๋ฅผ ๋‹ค์‹œ count์— ์ €์žฅํ•œ๋‹ค

์ด ์„ธ ๋™์ž‘ ์ค‘๊ฐ„์— ๋‹ค๋ฅธ ์Šค๋ ˆ๋“œ๊ฐ€ ๋ผ์–ด๋“ค๋ฉด, count ๊ฐ’์€ ์—‰๋šฑํ•˜๊ฒŒ ์ฆ๊ฐ€ํ•˜๊ฑฐ๋‚˜ ๊ฑด๋„ˆ๋›ฐ๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

 

์˜ˆ๋ฅผ ๋“ค์–ด, ๋‘ ์Šค๋ ˆ๋“œ๊ฐ€ ์•„๋ž˜์™€ ๊ฐ™์€ ์ˆœ์„œ๋กœ ์‹คํ–‰๋œ๋‹ค๊ณ  ํ•ด๋ด…์‹œ๋‹ค.

- ์Šค๋ ˆ๋“œ A: count ๊ฐ’์„ ์ฝ์Œ → (count == 0)
- ์Šค๋ ˆ๋“œ B: count ๊ฐ’์„ ์ฝ์Œ → (count == 0)
- ์Šค๋ ˆ๋“œ A: 1์„ ๋”ํ•ด 1 ์ €์žฅ
- ์Šค๋ ˆ๋“œ B: 1์„ ๋”ํ•ด 1 ์ €์žฅ

 

๊ฒฐ๊ณผ์ ์œผ๋กœ ๋‘ ๋ฒˆ ์ฆ๊ฐ€ํ–ˆ์ง€๋งŒ ์‹ค์ œ ๊ฐ’์€ 1์ž…๋‹ˆ๋‹ค.

 

์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๋ ค๋ฉด, ๊ณต์œ  ์ž์›์— ๋Œ€ํ•ด ์Šค๋ ˆ๋“œ๋“ค์ด ์ˆœ์„œ๋Œ€๋กœ ์ ‘๊ทผํ•˜๋„๋ก "๋™๊ธฐํ™”" ์ž‘์—…์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.


๐Ÿงช ํ•ด๊ฒฐ ์ „๋žต

๊ฒฝ์Ÿ ์ƒํƒœ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•œ ๋™๊ธฐํ™” ๋ฉ”์ปค๋‹ˆ์ฆ˜์œผ๋กœ ์ƒํ˜ธ๋ฐฐ์ œ์— ๋Œ€ํ•ด ์•Œ์•„๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

๐Ÿ’ก ์ƒํ˜ธ๋ฐฐ์ œ(Mutual Exclusion)

์ผ๋ฐ˜์ ์ธ ํ”„๋กœ์„ธ์Šค ๋‚ด ์ฝ”๋“œ ๊ตฌ์กฐ์ž…๋‹ˆ๋‹ค.

์ฝ”๋“œ ์ค‘ ๊ณต์œ  ์ž์›์— ์ ‘๊ทผํ•˜๋Š” ๊ตฌ์—ญ์„ ์ž„๊ณ„ ๊ตฌ์—ญ(critical section)์ด๋ผ๊ณ  ํ•ฉ๋‹ˆ๋‹ค.

๐Ÿ“Œ ์ž„๊ณ„ ๊ตฌ์—ญ์ด๋ž€? (critical section?)

๋‘˜ ์ด์ƒ์˜ ํ”„๋กœ์„ธ์Šค์—์„œ ๋™์‹œ์— ์ ‘๊ทผํ•ด์„œ๋Š” ์•ˆ ๋˜๋Š” ๊ณต์œ  ์ž์›์— ์ ‘๊ทผํ•˜๋Š” ์ฝ”๋“œ ๊ตฌ์—ญ
(a piece of code that accesses a shared resources(data structure or device) that must not be concurrently accessed by more than one processes.)

 

์—ฌ๋Ÿฌ ์Šค๋ ˆ๋“œ๊ฐ€ ๋™์‹œ์— ์ž„๊ณ„ ๊ตฌ์—ญ์— ์ง„์ž…ํ•œ๋‹ค๋ฉด ๊ฒฝ์Ÿ ์ƒํƒœ๊ฐ€ ๋ฐœ์ƒํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

๊ทธ๋ž˜์„œ ์ด๋ฅผ ๋ฐฉ์ง€ํ•˜๋Š” ๋ฌธ์ œ๋ฅผ ์ž„๊ณ„ ๊ตฌ์—ญ ๋ฌธ์ œ(Critical Section Problem)์ด๋ผ๊ณ  ๋ถ€๋ฅด๊ธฐ๋„ ํ•ฉ๋‹ˆ๋‹ค.

 

์ด๋ฅผ ๋ง‰๊ธฐ ์œ„ํ•ด ์Šค๋ ˆ๋“œ๊ฐ€ ์ž„๊ณ„ ๊ตฌ์—ญ์— ๋“ค์–ด๊ฐ€๊ธฐ ์ „์—

์ž์‹ ์ด ์ž„๊ณ„ ๊ตฌ์—ญ์—์„œ ์ž‘์—…ํ•˜๋Š” ๋™์•ˆ ๋‹ค๋ฅธ ์Šค๋ ˆ๋“œ๋“ค์ด ์ง„์ž…ํ•˜์ง€ ๋ชปํ•˜๋„๋ก lock์„ ์„ค์ •ํ•˜๊ณ ,

์ž„๊ณ„ ๊ตฌ์—ญ์—์„œ์˜ ์ž‘์—…์ด ๋๋‚˜๋ฉด lock์„ ํ•ด์ œํ•˜๋Š” ๋™์ž‘์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.

 

์ฆ‰, ์ด๋ฏธ ํ•œ ์Šค๋ ˆ๋“œ๊ฐ€ ์ž„๊ณ„ ๊ตฌ์—ญ์—์„œ ์ž‘์—… ์ค‘์ด๋ผ๋ฉด ๋‹ค๋ฅธ ์Šค๋ ˆ๋“œ๋Š” ์ž„๊ณ„ ๊ตฌ์—ญ์— ์ง„์ž…ํ•˜๋ฉด ์•ˆ ๋ฉ๋‹ˆ๋‹ค.

์ด๋ฅผ ์ƒํ˜ธ ๋ฐฐ์ œ(Mutual Exclusion)์ด๋ผ๊ณ  ํ•ฉ๋‹ˆ๋‹ค.

 

๋‹ค์Œ์€ ๋ฉ€ํ‹ฐ์Šค๋ ˆ๋“œ ํ™˜๊ฒฝ์—์„œ ์ƒํ˜ธ๋ฐฐ์ œ๋ฅผ ๊ตฌํ˜„ํ•˜๋Š” ๋Œ€ํ‘œ์ ์ธ ๋‘ ๊ฐ€์ง€ ๋™๊ธฐํ™” ๋ฉ”์ปค๋‹ˆ์ฆ˜

๋ฎคํ…์Šค์™€ ์„ธ๋งˆํฌ์–ด์— ๋Œ€ํ•ด ์‚ดํŽด๋ด…์‹œ๋‹ค.

โœ… ๋ฎคํ…์Šค(Mutex)

"ํ•œ ๋ฒˆ์— ํ•˜๋‚˜๋งŒ ๋“ค์–ด์˜ฌ ์ˆ˜ ์žˆ๋‹ค"

 

๊ณต์œ  ์ž์›์— ๋Œ€ํ•ด ํ•œ ๋ฒˆ์— ํ•˜๋‚˜์˜ ์Šค๋ ˆ๋“œ๋งŒ ์ ‘๊ทผ ๊ฐ€๋Šฅํ•œ ์ „๋žต์ž…๋‹ˆ๋‹ค.

 

ํ•œ ์Šค๋ ˆ๋“œ๊ฐ€ ์ž์›์— ์ ‘๊ทผํ•˜๋ฉด ํ’€๋ฆด ๋•Œ๊นŒ์ง€ ๋ฝ(lock)์ด ๊ฑธ๋ฆฝ๋‹ˆ๋‹ค.

์ด ๋ฝ์„ ํ’€ ์ˆ˜ ์žˆ๋Š” ๊ฑด ๋ฝ์„ ๊ฑด ํ•ด๋‹น ์Šค๋ ˆ๋“œ ๋ฟ์ž…๋‹ˆ๋‹ค.

์ด ์ž์›์— ์ ‘๊ทผํ•˜๊ณ ์ž ํ•˜๋Š” ๋‚˜๋จธ์ง€ ์Šค๋ ˆ๋“œ๋Š” ๋ฝ์ด ํ’€๋ฆด ๋•Œ๊นŒ์ง€ ๊ธฐ๋‹ค๋ฆฝ๋‹ˆ๋‹ค.

 

Java์—์„œ๋Š” ์•„๋ž˜์™€ ๊ฐ™์ด synchronized ํ‚ค์›Œ๋“œ๋ฅผ ๋ฉ”์„œ๋“œ์— ๋ถ™์—ฌ increment() ๋ฉ”์„œ๋“œ ์‹คํ–‰ ์ „ํ›„๋กœ ๋ฝ์„ ๊ฑธ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

public synchronized void increment() {
    count++;
}

 

synchronized ํ‚ค์›Œ๋“œ๋ฅผ ์ด์šฉํ•œ ๊ฒฝ์šฐ ์ž‘์—…์ด ๋๋‚œ ์Šค๋ ˆ๋“œ๊ฐ€ ๋ฝ์„ ๋ฐ˜ํ™˜ํ•  ๋•Œ, ๋‹ค์Œ์œผ๋กœ ๋ฝ์„ ํš๋“ํ•  ์Šค๋ ˆ๋“œ๊ฐ€ ์–ด๋–ค ์Šค๋ ˆ๋“œ์ผ์ง€์— ๋Œ€ํ•œ ๋ณด์žฅ์ด ์—†๊ธฐ ๋•Œ๋ฌธ์—

์–ด๋–ค ์Šค๋ ˆ๋“œ๋Š” ๋ฝ์„ ํš๋“ํ•˜์ง€ ๋ชปํ•˜๊ณ , ๊ณ„์† ์ ‘๊ทผ์„ ๊ธฐ๋‹ค๋ฆฌ๋Š” ๊ธฐ์•„ ์ƒํƒœ๊ฐ€ ๋  ๊ฐ€๋Šฅ์„ฑ์ด ์žˆ์Šต๋‹ˆ๋‹ค.

(์ผ๋ฐ˜์ ์œผ๋กœ๋Š” JVM์ด ๊ณต์ •ํ•˜๊ฒŒ ๋ฝ์„ ๋ถ„๋ฐฐํ•˜๋ ค ํ•ฉ๋‹ˆ๋‹ค.)

 

์ด๋Ÿฌํ•œ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด ๋ช…์‹œ์  ๋ฝ์„ ์‚ฌ์šฉํ•˜๊ธฐ๋„ ํ•ฉ๋‹ˆ๋‹ค. ๋Œ€ํ‘œ์ ์ธ ์˜ˆ๋กœ Java์˜ ReentrantLock์ด ์žˆ์Šต๋‹ˆ๋‹ค. 

private final ReentrantLock lock = new ReentrantLock();

public void increment() {
    lock.lock();
    try {
        count++;
    } finally {
        lock.unlock();
    }
}

 

syncronized ํ‚ค์›Œ๋“œ์™€ ๋ช…์‹œ์  ๋ฝ ๋ชจ๋‘ ๋‹ค๋ฅธ ์Šค๋ ˆ๋“œ์—์„œ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒŒ ์•„๋‹ˆ๋ผ ํ•˜๋‚˜์˜ ์Šค๋ ˆ๋“œ ๋‚ด์—์„œ๋งŒ ์ผ์–ด๋‚˜๋Š” ์ผ์ž…๋‹ˆ๋‹ค.

๋”ฐ๋ผ์„œ ๋ฎคํ…์Šค์—์„œ๋Š” ๋ฝ์„ ํš๋“ํ•œ ์Šค๋ ˆ๋“œ๋งŒ์ด ๋ฝ์„ ํ•ด์ œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ด์ฒ˜๋Ÿผ ๋ฎคํ…์Šค์—์„œ ๋ฝ์€ ์†Œ์œ ๊ถŒ์˜ ๊ฐœ๋…์ด ์žˆ์Šต๋‹ˆ๋‹ค.

๋ฎคํ…์Šค์˜ ๋ชฉ์ ์€ ํ•œ ์Šค๋ ˆ๋“œ๊ฐ€ ์–ด๋–ค ๊ณต์œ  ์ž์›์— ๋Œ€ํ•ด ๋…์ ์ ์œผ๋กœ ์ž‘์—…์„ ๋๋งˆ์น  ๋•Œ๊นŒ์ง€ ๋ณดํ˜ธํ•˜๋Š” ๊ฒƒ์ด๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.

 

๐Ÿ”‘ ๋ฎคํ…์Šค์—์„œ ํ•ต์‹ฌ์€ ํ•œ ๋ฒˆ์— ํ•˜๋‚˜์˜ ์Šค๋ ˆ๋“œ๋งŒ ์ ‘๊ทผ ๊ฐ€๋Šฅํ•˜๋„๋ก ๋ณด์žฅํ•œ๋‹ค๋Š” ์ ์ž…๋‹ˆ๋‹ค.

 

โœ… ์„ธ๋งˆํฌ์–ด(Semaphore)

์„ธ๋งˆํฌ์–ด ์—ญ์‹œ ๊ณต์œ ์ž์›์— ์—ฌ๋Ÿฌ ์Šค๋ ˆ๋“œ๊ฐ€ ์ ‘๊ทผ๋˜๋Š” ๊ฒƒ์„ ๋ง‰๋Š” ๋ฐฉ๋ฒ•์ด์ง€๋งŒ

๋ฎคํ…์Šค์™€ ๋‹ค๋ฅด๊ฒŒ ๋ฐ˜๋“œ์‹œ ํ•œ ๋ฒˆ์— ํ•˜๋‚˜์˜ ์Šค๋ ˆ๋“œ๋งŒ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒƒ์€ ์•„๋‹™๋‹ˆ๋‹ค.

์„ธ๋งˆํฌ์–ด์—์„œ๋Š” ๋™์‹œ์— ์ •ํ•ด์ง„ ๊ฐœ์ˆ˜๋งŒํผ์˜ ์Šค๋ ˆ๋“œ๊ฐ€ ๊ณต์œ  ์ž์›์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

Semaphore๋ผ๋Š” ์ •์ˆ˜ํ˜• ์นด์šดํ„ฐ ๋ณ€์ˆ˜(๋ณดํ†ต s๋กœ ํ‘œ์‹œ)๋ฅผ ์ด์šฉํ•˜์—ฌ ๋™์‹œ์— ๊ณต์œ  ์ž์›์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋Š” ์Šค๋ ˆ๋“œ์˜ ์ˆ˜๋ฅผ ์ œํ•œํ•ฉ๋‹ˆ๋‹ค.

์ฒ˜์Œ์— ๊ณต์œ  ์ž์›์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋Š” ๋™์‹œ ์Šค๋ ˆ๋“œ ์ˆ˜๋ฅผ N๊ฐœ๋กœ ์ •ํ•˜๋ฉด, ์ตœ๋Œ€ N๊ฐœ๋งŒ ๋™์‹œ์— ์ž„๊ณ„ ๊ตฌ์—ญ์— ์ง„์ž…ํ•  ์ˆ˜ ์žˆ๊ณ ,

๊ทธ๋ณด๋‹ค ๋” ๋งŽ์€ ์Šค๋ ˆ๋“œ๊ฐ€ ์ ‘๊ทผํ•˜๋ ค๊ณ  ํ•˜๋ฉด ๋จผ์ € ๋“ค์–ด๊ฐ€ ์žˆ๋˜ ์Šค๋ ˆ๋“œ๊ฐ€ ๋‚˜์˜ฌ ๋•Œ๊นŒ์ง€ ๊ธฐ๋‹ค๋ ค์•ผ ํ•ฉ๋‹ˆ๋‹ค.


"์•„๋‹ˆ.. ๋™์‹œ์— ํ•˜๋‚˜์˜ ์Šค๋ ˆ๋“œ๋งŒ ์ž„๊ณ„ ๊ตฌ์—ญ์— ๋“ค์–ด๊ฐ€์•ผ ํ•œ๋‹ค๋ฉด์„œ์š”?! ์„ธ๋งˆํฌ์–ด๊ฐ€ ์ƒํ˜ธ๋ฐฐ์ œ์ธ ๊ฑฐ ๋งž์•„์š”?"

 

๊ฒฝ์Ÿ ์ƒํƒœ๋ฅผ ๋ง‰๊ธฐ ์œ„ํ•ด ํ•œ ์‹œ์ ์— ์˜ค์ง ํ•˜๋‚˜์˜ ์Šค๋ ˆ๋“œ๋งŒ ๊ณต์œ  ์ž์›์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋„๋ก ์ œํ•œํ•˜๋Š” ๊ฒƒ์ด ์ƒํ˜ธ ๋ฐฐ์ œ์ž…๋‹ˆ๋‹ค.

์ƒํ˜ธ ๋ฐฐ์ œ๋ฅผ ๊ตฌํ˜„ํ•˜๋Š” ๋„๊ตฌ๋กœ ์˜ค๋Š˜ ์‚ดํŽด๋ณธ ๋ฎคํ…์Šค์™€ ์„ธ๋งˆํฌ์–ด ๋“ฑ์ด ์žˆ๋Š”๊ฑฐ์ฃ .

๋งŒ์•ฝ ์„ธ๋งˆํฌ์–ด์—์„œ ๋™์‹œ์— ๊ณต์œ  ์ž์›์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋Š” ์Šค๋ ˆ๋“œ์˜ ๊ฐœ์ˆ˜๋ฅผ "1๊ฐœ"๋กœ ์„ค์ •ํ•œ๋‹ค๋ฉด

๋ฎคํ…์Šค์ฒ˜๋Ÿผ ํ•œ ๋ฒˆ์— ํ•˜๋‚˜์˜ ์Šค๋ ˆ๋“œ๋งŒ ๋“ค์–ด๊ฐ€๊ฒ ์ฃ ? ์ด๋Ÿฌํ•œ ์„ธ๋งˆํฌ์–ด๋ฅผ Binary Semaphore๋ผ๊ณ  ํ•ฉ๋‹ˆ๋‹ค.

Binary Semaphore๋กœ ๊ตฌํ˜„ํ•˜๋ฉด ์ƒํ˜ธ ๋ฐฐ์ œ๋ฅผ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์˜ค๋Š˜ ๋ฐฐ์šด ์ƒํ˜ธ ๋ฐฐ์ œ ์™ธ์—๋„ ๋™๊ธฐํ™” ์šฉ๋„๋กœ ์„ธ๋งˆํฌ์–ด๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ๋„ ํ•ฉ๋‹ˆ๋‹ค.

 

์ด Semaphore์—์„œ๋Š” P ์—ฐ์‚ฐ๊ณผ V ์—ฐ์‚ฐ์„ ์ด์šฉํ•ด ์ž์›์— ์ ‘๊ทผํ•ฉ๋‹ˆ๋‹ค.

P()๋Š” ์ž„๊ณ„ ๊ตฌ์—ญ์— ์ง„์ž…ํ•˜๊ณ ์ž ํ•  ๋•Œ ํ˜ธ์ถœํ•˜๊ณ , V()๋Š” ์ž„๊ณ„ ๊ตฌ์—ญ์—์„œ ๋‚˜์˜ฌ ๋•Œ ํ˜ธ์ถœํ•ฉ๋‹ˆ๋‹ค.

P(s) {

    while(S <= 0) {
    	do wait; // no operation
    }
    S--;
}

V(s) {
	S++;
}

 

๐Ÿ“Œ P ์—ฐ์‚ฐ

๊ณต์œ  ์ž์›์„ ์–ป๊ธฐ ์œ„ํ•ด ์ž„๊ณ„ ๊ตฌ์—ญ์— ๋“ค์–ด๊ฐ€๊ธฐ ์ „ entry section(์ง„์ž… ๊ตฌ๊ฐ„)์—์„œ P ์—ฐ์‚ฐ์„ ํ•ฉ๋‹ˆ๋‹ค.

์ด๋•Œ ์„ธ๋งˆํฌ์–ด ๊ฐ’์„ ์ ๊ฒ€ํ•˜์—ฌ ๋ˆ„๊ตฐ๊ฐ€ ์ด ์ž์›์„ ์‚ฌ์šฉํ•˜๋Š”์ง€ ์•Œ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

๋งŒ์•ฝ ์„ธ๋งˆํฌ์–ด s > 0 ์ด๋ฉด, ํ•ด๋‹น ์Šค๋ ˆ๋“œ๊ฐ€ ์ž์›์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ์˜๋ฏธ์ž…๋‹ˆ๋‹ค.

s๋ฅผ 1 ๊ฐ์†Œ์‹œํ‚ค๊ณ  ์ž„๊ณ„ ๊ตฌ์—ญ์— ์ง„์ž…ํ•ฉ๋‹ˆ๋‹ค.

 

๋ฐ˜๋ฉด s <= 0์ด๋ฉด ๋‹ค๋ฅธ ์Šค๋ ˆ๋“œ๊ฐ€ ์ด๋ฏธ ์ž„๊ณ„ ๊ตฌ์—ญ์—์„œ ์ž‘์—… ์ค‘์ด๋ผ๋Š” ์˜๋ฏธ์ด๋ฏ€๋กœ s๊ฐ€ ๋‹ค์‹œ ์–‘์ˆ˜๊ฐ€ ๋  ๋•Œ๊นŒ์ง€ ๋Œ€๊ธฐํ•ฉ๋‹ˆ๋‹ค.

 

์ด๋•Œ s๋Š” ๋ฌด์—‡์„ ์˜๋ฏธํ• ๊นŒ์š”? ๋ฐ”๋กœ "ํ˜„์žฌ ์ž„๊ณ„ ๊ตฌ์—ญ์— ์ง„์ž… ๊ฐ€๋Šฅํ•œ ์Šค๋ ˆ๋“œ์˜ ์ˆ˜"์ž…๋‹ˆ๋‹ค.

 

๐Ÿ“Œ V ์—ฐ์‚ฐ

V์—ฐ์‚ฐ์€ ์ ์œ ํ•˜๊ณ  ์žˆ๋˜ ๊ณต์œ  ์ž์›์„ ํ’€์–ด์ฃผ๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์ž„๊ณ„ ๊ตฌ์—ญ์—์„œ ๋ฒ—์–ด๋‚˜ exit section์— ์ ‘์–ด๋“ค ๋•Œ V ์—ฐ์‚ฐ์„ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค.

 

์Šค๋ ˆ๋“œ๊ฐ€ ๊ณต์œ  ์ž์›์— ๋Œ€ํ•œ ์ž‘์—…์„ ๋๋‚ด๋ฉด ์„ธ๋งˆํฌ์–ด s์˜ ๊ฐ’์ด 1 ์ฆ๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.

์ด๋•Œ ๋Œ€๊ธฐํ•˜๊ณ  ์žˆ๋˜(sleep ์ƒํƒœ์ด๋˜) ์Šค๋ ˆ๋“œ๊ฐ€ ์žˆ์—ˆ๋‹ค๋ฉด ์ž ์—์„œ ๊นจ์–ด๋‚˜ ๊ณต์œ  ์ž์›์— ์ ‘๊ทผํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

 

์„ธ๋งˆํฌ์–ด๋Š” ๋ฎคํ…์Šค์™€ ๋‹ฌ๋ฆฌ ๋ฝ์— ๋Œ€ํ•œ ์†Œ์œ ๊ถŒ ๊ฐœ๋…์ด ์—†๋Š” ๊ณต์œ  ์ž์› ์ ‘๊ทผ ์ œ์–ด ๋„๊ตฌ์ž…๋‹ˆ๋‹ค.

์„ธ๋งˆํฌ์–ด๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์–ด๋–ค ์Šค๋ ˆ๋“œ๋ผ๋„ V ์—ฐ์‚ฐ์œผ๋กœ ์„ธ๋งˆํฌ์–ด ๊ฐ’์„ ์ฆ๊ฐ€์‹œ์ผœ ์ž์›์„ ํ•ด์ œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

V ์—ฐ์‚ฐ์€ “๊ณต์œ  ์ž์›์˜ ์‚ฌ์šฉ์ด ๋๋‚ฌ์Œ์„ ์•Œ๋ฆด ์ฑ…์ž„์ด ์žˆ๋Š” ์Šค๋ ˆ๋“œ”๊ฐ€ ํ˜ธ์ถœํ•ฉ๋‹ˆ๋‹ค.
์ด ์Šค๋ ˆ๋“œ๋Š” ๋ฐ˜๋“œ์‹œ P ์—ฐ์‚ฐ์„ ํ–ˆ๋˜ ๊ฐ™์€ ์Šค๋ ˆ๋“œ์ผ ํ•„์š”๋Š” ์—†์Šต๋‹ˆ๋‹ค. (๋ฌผ๋ก  ๊ฐ™์•„๋„ ๋ฉ๋‹ˆ๋‹ค.)

 

์˜ˆ๋ฅผ ๋“ค์–ด ์ด๋Ÿฐ ๊ฒฝ์šฐ๊ฐ€ ์žˆ๋‹ค๊ณ  ํ•ฉ์‹œ๋‹ค. (์ฐธ๊ณ ๋กœ ์ด ์˜ˆ์‹œ๋Š” ์šด์˜์ฒด์ œ์—์„œ ๋งŽ์ด ์˜ˆ์‹œ๋กœ ๋“œ๋Š” ์ƒ์‚ฐ์ž - ์†Œ๋น„์ž ๋ฌธ์ œ๋ฅผ ๋‹จ์ˆœํ™”ํ•œ ๋ฒ„์ „์ž…๋‹ˆ๋‹ค.)

  • ๐Ÿง‘‍๐ŸŒพ ์ƒ์‚ฐ์ž Producer: ์ƒํ’ˆ์„ ์ƒ์‚ฐํ•ด ๋งˆํŠธ์— ๋‚ฉํ’ˆํ•จ
  • ๐Ÿงบ ์†Œ๋น„์ž Consumer: ๋งˆํŠธ์—์„œ ์ƒํ’ˆ์„ ๊ตฌ์ž…ํ•จ
  • ๋ฌธ์ œ: ์†Œ๋น„์ž๋Š” ๋งˆํŠธ์— ์ƒํ’ˆ์ด ์—†์œผ๋ฉด ๊ธฐ๋‹ค๋ ค์•ผ ํ•จ
    • โžก๏ธ ์ƒ์‚ฐ์ž๊ฐ€ ๋งˆํŠธ์— ๋‚ฉํ’ˆํ–ˆ์„ ๋•Œ ์†Œ๋น„์ž์—๊ฒŒ "์ด์ œ ์‚ฌ!"ํ•˜๊ณ  ์‹ ํ˜ธ๋ฅผ ์ค˜์•ผ ํ•จ

์ด๋•Œ ์„ธ๋งˆํฌ์–ด๋Š” ํ˜„์žฌ ๋งˆํŠธ์— ์ƒํ’ˆ ์žฌ๊ณ ๊ฐ€ ๋ช‡ ๊ฐœ ์žˆ๋Š”์ง€๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” ์ˆซ์ž ์นด์šดํ„ฐ์ž…๋‹ˆ๋‹ค.

Semaphore items = new Semaphore(0);  // ํ˜„์žฌ ๋งˆํŠธ์— ์ƒํ’ˆ์ด 0๊ฐœ ์žˆ๋‹ค๊ณ  ๊ฐ€์ •

Thread producer = new Thread(() -> {
    while (true) {
        produceItem();
        items.release();  // V ์—ฐ์‚ฐ! ์ƒํ’ˆ ํ•˜๋‚˜ ์ถ”๊ฐ€ํ–ˆ์–ด!
    }
});

Thread consumer = new Thread(() -> {
    while (true) {
        items.acquire();  // P ์—ฐ์‚ฐ! ์žฌ๊ณ ๊ฐ€ ์—†์œผ๋ฉด ๊ธฐ๋‹ค๋ฆผ
        consumeItem();	// ์ƒํ’ˆ ๊ตฌ์ž…
    }
});

 

Producer๋Š” V ์—ฐ์‚ฐ๋งŒ, Consumer๋Š” P ์—ฐ์‚ฐ๋งŒ ํ•ฉ๋‹ˆ๋‹ค.

์ด๋กœ์จ ์ƒ์‚ฐ์ž๋Š” ์†Œ๋น„์ž์—๊ฒŒ ๋ฌผ๊ฑด์„ ์ถ”๊ฐ€ํ–ˆ๋‹ค๊ณ  ์•Œ๋ฆฌ๊ณ , ์†Œ๋น„์ž๋Š” ์ƒ์‚ฐ์ž์—๊ฒŒ ๋ฌผ๊ฑด์ด ํ•„์š”ํ•˜๋‹ค๊ณ  ์•Œ๋ฆด ์ˆ˜ ์žˆ์ฃ .

 

์„ธ๋งˆํฌ์–ด๋Š” "๋ˆ„๊ฐ€" ์ž์›์— ์ ‘๊ทผํ–ˆ๋Š”์ง€๊ฐ€ ์ค‘์š”ํ•œ ๊ฒŒ ์•„๋‹ˆ๋ผ
"๋ช‡ ๊ฐœ์˜ ์Šค๋ ˆ๋“œ"๊ฐ€ ์ž์›์— ์ ‘๊ทผํ–ˆ๋Š”์ง€๊ฐ€ ์ค‘์š”ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋ˆ„๊ตฌ๋‚˜ ๋ฝ์„ ํ•ด์ œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

 

์ •๋ฆฌํ•˜์ž๋ฉด,

 

๋ฎคํ…์Šค์—์„œ๋Š” ํ•˜๋‚˜์˜ ์ž์›์— ๋™์‹œ์— ํ•˜๋‚˜์˜ ์Šค๋ ˆ๋“œ๋งŒ์ด ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ์—ˆ๊ณ , ๋ฝ์„ ์„ค์ •ํ•œ ์Šค๋ ˆ๋“œ๋งŒ ๋ฝ์„ ํ•ด์ œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

(๋™๊ธฐํ™” ๋Œ€์ƒ์ด ํ•˜๋‚˜)

์„ธ๋งˆํฌ์–ด์—์„œ๋Š” ๋ฏธ๋ฆฌ ์ง€์ •ํ•œ ์ตœ๋Œ€ N๊ฐœ์˜ ์Šค๋ ˆ๋“œ๊ฐ€ ํ•˜๋‚˜์˜ ์ž์›์— ๋™์‹œ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ˆ„๊ตฌ๋‚˜ ๋ฝ์„ ํ•ด์ œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

(๋™๊ธฐํ™” ๋Œ€์ƒ์ด ํ•˜๋‚˜ ์ด์ƒ)


๐Ÿ’ก ์š”์•ฝ

๋ฉ€ํ‹ฐ์Šค๋ ˆ๋“œ ํ™˜๊ฒฝ์—์„œ๋Š”

์—ฌ๋Ÿฌ ์Šค๋ ˆ๋“œ๊ฐ€ ๊ณต์œ  ์ž์›์— ๋™์‹œ์— ์ ‘๊ทผํ•˜๋ฉด์„œ

๋ฐ์ดํ„ฐ ๋ถˆ์ผ์น˜๋‚˜ ์˜ˆ๊ธฐ์น˜ ์•Š์€ ๋™์ž‘ ๋ฌธ์ œ๊ฐ€ ์ผ์–ด๋‚  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

์ด๋ฅผ ๋ฐฉ์ง€ํ•˜๋ ค๋ฉด ๋™์‹œ์— ์‹คํ–‰๋˜๋Š” ์Šค๋ ˆ๋“œ ๊ฐ„ ์ž์› ์ ‘๊ทผ์„ ์กฐ์œจํ•ด์•ผ ํ•˜๋ฉฐ,
์ด๋ฅผ ์œ„ํ•ด ๋ฎคํ…์Šค(Mutex), ์„ธ๋งˆํฌ์–ด(Semaphore)์™€ ๊ฐ™์€ ๋™๊ธฐํ™” ๋„๊ตฌ๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

 

  • ๐Ÿงต ๋ฉ€ํ‹ฐ์Šค๋ ˆ๋“œ ํ™˜๊ฒฝ(Multi-Thread): ๋™์‹œ์— ์—ฌ๋Ÿฌ ์ž‘์—…์ด ๊ฐ€๋Šฅํ•˜์ง€๋งŒ, ๊ณต์œ  ์ž์› ์ถฉ๋Œ ์œ„ํ—˜์ด ์žˆ์Œ
  • โš ๏ธ ๊ฒฝ์Ÿ ์ƒํƒœ(Race Condition): ์—ฌ๋Ÿฌ ์Šค๋ ˆ๋“œ๊ฐ€ ๋™์‹œ์— ๊ฐ™์€ ์ž์›์— ์ ‘๊ทผํ•  ๋•Œ ์‹คํ–‰ ์ˆœ์„œ์— ๋”ฐ๋ผ ์˜ค๋ฅ˜ ๋ฐœ์ƒ
  • โœ… ์ƒํ˜ธ ๋ฐฐ์ œ(Mutual Exclusion): ์ด๋ฏธ ์ž„๊ณ„ ๊ตฌ์—ญ(critical section)์—์„œ ์ž‘์—… ์ค‘์ธ ์Šค๋ ˆ๋“œ๊ฐ€ ์žˆ๋‹ค๋ฉด, ๋‹ค๋ฅธ ์Šค๋ ˆ๋“œ๋Š” ์ ‘๊ทผ ๋ถˆ๊ฐ€
  • ๐Ÿ”’ ๋ฎคํ…์Šค (Mutex): ํ•œ ๋ฒˆ์— ํ•˜๋‚˜๋งŒ ์ ‘๊ทผ ๊ฐ€๋Šฅ, ๋ฝ ์†Œ์œ ์ž๋งŒ ํ•ด์ œ ๊ฐ€๋Šฅ
  • ๐ŸŸข ์„ธ๋งˆํฌ์–ด (Semaphore): ๋™์‹œ์— ์—ฌ๋Ÿฌ ์Šค๋ ˆ๋“œ ์ ‘๊ทผ ๊ฐ€๋Šฅ, ์†Œ์œ ์ž ๊ด€๊ณ„ ์—†์ด ํ•ด์ œ ๊ฐ€๋Šฅ

 

์ฐธ๊ณ ์ž๋ฃŒ

๋ฐ˜์‘ํ˜•