๊ฒฝ์Ÿ ์ƒํƒœ

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

// ์ƒ์‚ฐ์ž
while (true) {
	/* produce an item in next_produced */
	
	while (count == BUFFER_SIZE)
		; /* do noting */
		
	buffer[in] = next_produced;
	in = (in + 1) % BUFFER_SIZE;
	count++;
}

// ์†Œ๋น„์ž
while (true) {
	while (count == 0)
		; /* do nothing */
		
	next_consumed = buffer[out];
	out = (out + 1) % BUFFER_SIZE;
	count--;
	
	/* consume the item in next_consumed */
}

count ๊ฐ’์„ ์ฆ๊ฐ€์‹œํ‚ค๊ณ  ๊ฐ์†Œ์‹œํ‚ค๋Š” ์ƒ์‚ฐ์ž/์†Œ๋น„์ž ์ฝ”๋“œ์ด๋‹ค. ์ƒ์‚ฐ์ž๋Š” count๊ฐ€ ๋ฒ„ํผ ์‚ฌ์ด์ฆˆ๋ณด๋‹ค ์ž‘์•„์ง€๊ธฐ ์ „๊นŒ์ง€ ์•„๋ฌด๋Ÿฐ ํ–‰๋™์„ ํ•˜์ง€ ์•Š๊ณ , ์†Œ๋น„์ž๋Š” count๊ฐ€ 0์ด ์•„๋‹๋•Œ ๊นŒ์ง€ ์•„๋ฌด๋Ÿฐ ํ–‰๋™์„ ํ•˜์ง€ ์•Š๋Š”๋‹ค. ์—ฌ๊ธฐ์„œ count๋Š” ์ „์—ญ ๋ณ€์ˆ˜๋ผ๊ณ  ๊ฐ€์ •์„ ํ•˜์ž.

ํ˜„์žฌ count์˜ ๊ฐ’์ด 10์ผ ๋•Œ, ์ƒ์‚ฐ์ž์™€ ์†Œ๋น„์ž ์ฝ”๋“œ๋ฅผ ๋ณ‘๋ ฌ๋กœ ์‹คํ–‰์„ ํ•œ๋‹ค๋ฉด ์–ด๋–ค ๊ฒฐ๊ณผ๊ฐ€ ๋‚˜์˜ฌ๊นŒ? 10์ด ๊ทธ๋Œ€๋กœ ์œ ์ง€๋  ๊ฒƒ์œผ๋กœ ์ƒ๊ฐํ•˜์ง€๋งŒ, ์‹ค์ œ๋กœ๋Š” 10์ด ๋‚˜์˜ฌ ์ˆ˜๋„ ์žˆ๊ณ  ์•„๋‹ ์ˆ˜๋„ ์žˆ๋‹ค. ์ด์œ ๋Š” ์ฆ๊ฐ ์—ฐ์‚ฐ์ž์— ์žˆ๋‹ค.

์ฆ๊ฐ ์—ฐ์‚ฐ์ž(++, โ€”)๊ฐ€ ๊ธฐ๊ณ„์–ด๋กœ ์ปดํŒŒ์ผ๋์„ ๋•Œ, ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๋‚ด๋ถ€ ๋™์ž‘์„ ๊ฐ€์ง€๊ฒŒ ๋œ๋‹ค.

register_1 = count
register_1 = register_1 + 1
count = register_1

์ฆ๊ฐ ์—ฐ์‚ฐ์ž๊ฐ€ 3๊ฐœ์˜ ๋ช…๋ น์–ด๋กœ ๋‚˜๋ˆ ์„œ ์‹คํ–‰๋˜๊ณ  ์žˆ๋‹ค. ์ด๋•Œ, ๊ฐ ๋ช…๋ น์–ด๋ฅผ ์ˆ˜ํ–‰ํ•˜๋Š” ์ค‘๊ฐ„์ค‘๊ฐ„ ์ธํ„ฐ๋ŸฝํŠธ๊ฐ€ ๋ฐœ์ƒํ•˜์—ฌ ์ปจํ…์ŠคํŠธ ์Šค์œ„์นญ์ด ๋ฐœ์ƒํ•˜๊ฒŒ ๋œ๋‹ค๋ฉด ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค. register_1์—์„œ๋Š” 10์˜ ๊ฐ’์„ ์ฝ๊ณ  1์„ ์ฆ๊ฐ€์‹œ์ผฐ๋Š”๋ฐ ์ธํ„ฐ๋ŸฝํŠธ๊ฐ€ ๋ฐœ์ƒํ•˜์—ฌ ์†Œ๋น„์ž ์ฝ”๋“œ๊ฐ€ ์‹คํ–‰์ด ๋๋‹ค๊ณ  ํ•˜์ž. ๊ทธ๋Ÿผ ์†Œ๋น„์ž ์ฝ”๋“œ๋กœ ์ธํ•ด count์—๋Š” 9๋ผ๋Š” ๊ฐ’์ด ์ €์žฅ๋˜๊ณ , ์ธํ„ฐ๋ŸฝํŠธ๊ฐ€ ๋ฐœ์ƒํ•˜์—ฌ ์ปจํ…์ŠคํŠธ ์Šค์œ„์นญ์ด ๋ฐœ์ƒํ•˜๋ฉด ์ƒ์‚ฐ์ž ์ฝ”๋“œ์—์„œ๋Š” ์—ฌ์ „ํžˆ 11์ด๋ผ๋Š” ๊ฐ’์„ ๊ฐ€์ง€๊ณ  ์žˆ๊ธฐ ๋•Œ๋ฌธ์— count์˜ ๊ฐ’์ด 11์ด ๋˜๋ฒ„๋ฆฌ๋Š” ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค.

image.png

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

์ž„๊ณ„ ์˜์—ญ ๋ฌธ์ œ

๊ฐ ํ”„๋กœ์„ธ์Šค๋Š” ์ž„๊ณ„ ์˜์—ญ์ด๋ผ๋Š” ์ฝ”๋“œ ์˜์—ญ์„ ํฌํ•จํ•˜๊ณ  ์žˆ๋‹ค. ์ด ์˜์—ญ์€ ๋‹ค๋ฅธ ํ”„๋กœ์„ธ์Šค๋“ค์ด ์ ‘๊ทผํ•˜์—ฌ ๋ฐ์ดํ„ฐ๋ฅผ ์—…๋ฐ์ดํŠธ ํ•  ์ˆ˜ ์žˆ๋‹ค. ์ž„๊ณ„ ์˜์—ญ์˜ ์ค‘์š”ํ•œ ํŠน์ง•์€ ์ž„๊ณ„ ์˜์—ญ ๋‚ด๋ถ€์—์„œ ํ•˜๋‚˜์˜ ํ”„๋กœ์„ธ์Šค๊ฐ€ ์‹คํ–‰๋˜๊ณ  ์žˆ๋‹ค๋ฉด, ๋‹ค๋ฅธ ํ”„๋กœ์„ธ์Šค๋“ค์€ ์ž„๊ณ„ ์˜์—ญ์— ์ ‘๊ทผํ•  ์ˆ˜ ์—†๋‹ค.

๊ทธ๋ ‡๊ธฐ ๋•Œ๋ฌธ์—, ์ž„๊ณ„ ์˜์—ญ ๋ฌธ์ œ๋Š” ์„œ๋กœ ๋‹ค๋ฅธ ํ”„๋กœ์„ธ์Šค๋“ค์ด ๋™์‹œ์— ์ž„๊ณ„ ์˜์—ญ์— ์ ‘๊ทผํ•˜๋Š” ๊ฒƒ์„ ๋ง‰๋Š” ๊ฒƒ์ด๋‹ค. ์ž„๊ณ„ ์˜์—ญ์— ์ ‘๊ทผํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ์ ‘๊ทผ ๊ถŒํ•œ์„ ๋ฐ›์•„์•ผํ•˜๋Š”๋ฐ, ์ด๋•Œ ์ ‘๊ทผ ๊ถŒํ•œ์„ ์š”์ฒญํ•˜๋Š” ์ฝ”๋“œ ๋ถ€๋ถ„์„ ์ง„์ž… ๊ตฌ์—ญ์ด๋ผ๊ณ  ํ•œ๋‹ค. ์ž„๊ณ„ ์˜์—ญ์—์„œ ์ž‘์—…์ด ๋๋‚˜๊ณ  ๋‚˜์˜ค๋Š” ๋ถ€๋ถ„์„ ํ‡ด์ถœ ๊ตฌ์—ญ, ๊ทธ ์ด์™ธ์˜ ๋‚˜๋จธ์ง€ ์ฝ”๋“œ๋ฅผ ๋‚˜๋ฌด์ง€ ๊ตฌ์—ญ์ด๋ผ๊ณ  ๋ถ€๋ฅธ๋‹ค.

image.png

์ž„๊ณ„ ์˜์—ญ ๋ฌธ์ œ์— ๋Œ€ํ•œ ํ•ด๊ฒฐ์ฑ…์€ ์•„๋ž˜ ์„ธ ๊ฐ€์ง€ ์š”๊ตฌ ์กฐ๊ฑด์„ ๋งŒ์กฑํ•ด์•ผ ํ•œ๋‹ค.

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

๊ฒฝ์Ÿ ์ƒํƒœ ์„น์…˜์—์„œ ๋ฐœ์ƒํ•œ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด์„œ, ํ•˜๋‚˜์˜ ๋ช…๋ น์–ด๊ฐ€ ์‹คํ–‰๋  ๋™์•ˆ ์ธํ„ฐ๋ŸฝํŠธ๋ฅผ ๋ง‰๋Š” ๋ฐฉ๋ฒ•์ด ์กด์žฌํ•œ๋‹ค. ํ•˜์ง€๋งŒ, ์ด ๊ฒฝ์šฐ๋Š” ๋‹จ์ผ ์ฝ”์–ด์—์„œ๋Š” ๊ตฌํ˜„์ด ๊ฐ€๋Šฅํ• ์ง€๋ผ๋„ ๋ฉ€ํ‹ฐ ์ฝ”์–ด ํ™˜๊ฒฝ์—์„œ๋Š” ์„ฑ๋Šฅ์ด ์ €ํ•˜๋˜๋Š” ๋“ฑ ์ถ”๊ฐ€์ ์ธ ๋ฌธ์ œ๋ฅผ ๋ฐœ์ƒ์‹œํ‚จ๋‹ค.

๋™๊ธฐํ™”

ํ•˜๋“œ์›จ์–ด ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•

๋ฉ”๋ชจ๋ฆฌ ์žฅ๋ฒฝ

์ปดํ“จํ„ฐ ์•„ํ‚คํ…์ฒ˜๊ฐ€ ์‘์šฉ ํ”„๋กœ๊ทธ๋žจ์—๊ฒŒ ์ œ๊ณตํ•˜๋Š” ๋ฉ”๋ชจ๋ฆฌ ์ ‘๊ทผ ์‹œ ๋ณด์žฅ๋˜๋Š” ์‚ฌํ•ญ์„ ๊ฒฐ์ •ํ•œ ๋ฐฉ์‹์„ ๋ฉ”๋ชจ๋ฆฌ ๋ชจ๋ธ์ด๋ผ๊ณ  ํ•œ๋‹ค. ์ผ๋ฐ˜์ ์œผ๋กœ ๋‘ ๊ฐ€์ง€ ๋ฒ”์ฃผ ์ค‘ ํ•˜๋‚˜์— ์†ํ•œ๋‹ค.

  • ๊ฐ•ํ•œ ์ˆœ์„œ : ํ•œ ํ”„๋กœ์„ธ์„œ์˜ ๋ฉ”๋ชจ๋ฆฌ ๋ณ€๊ฒฝ ๊ฒฐ๊ณผ๊ฐ€ ๋‹ค๋ฅธ ๋ชจ๋“  ํ”„๋กœ์„ธ์„œ์— ์ฆ‰์‹œ ๋ณด์ž„
  • ์•ฝํ•œ ์ˆœ์„œ : ํ•œ ํ”„๋กœ์„ธ์„œ์˜ ๋ฉ”๋ชจ๋ฆฌ ๋ณ€๊ฒฝ ๊ฒฐ๊ณผ๊ฐ€ ๋‹ค๋ฅธ ํ”„๋กœ์„ธ์„œ์—๊ฒŒ ์ฆ‰์‹œ ๋ณด์ด์ง€ ์•Š์Œ

๋ฉ”๋ชจ๋ฆฌ ๋ชจ๋ธ์€ ํ”„๋กœ์„ธ์„œ ์œ ํ˜•์— ๋”ฐ๋ผ ๋‹ค๋ฅด๊ธฐ ๋•Œ๋ฌธ์— ์ปค๋„ ๊ฐœ๋ฐœ์ž๊ฐ€ ๋ฉ”๋ชจ๋ฆฌ ๋ณ€๊ฒฝ์˜ ๊ฐ€์‹œ์„ฑ์— ๋Œ€ํ•œ ๊ฐ€์ •์ด ๋ถˆ๊ฐ€๋Šฅํ•˜๋‹ค. ์ด๋Ÿฐ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด ๋ฉ”๋ชจ๋ฆฌ ์žฅ๋ฒฝ์„ ์‚ฌ์šฉํ•œ๋‹ค. ๋ฉ”๋ชจ๋ฆฌ ์žฅ๋ฒฝ์€ ๋‹ค๋ฅธ ํ”„๋กœ์„ธ์„œ์—์„œ ์‹คํ–‰ ์ค‘์ธ ์Šค๋ ˆ๋“œ์— ๋ฉ”๋ชจ๋ฆฌ ๋ณ€๊ฒฝ ์‚ฌํ•ญ์ด ๋ณด์ด๋Š” ๊ฒƒ์„ ๋ณด์žฅํ•˜๋Š” ๋ช…๋ น์–ด์ด๋‹ค.

๋ฉ”๋ชจ๋ฆฌ ์žฅ๋ฒฝ์€ ๋งค์šฐ ๋‚ฎ์€ ์ˆ˜์ค€์˜ ์—ฐ์‚ฐ์œผ๋กœ ๊ฐ„์ฃผํ•˜๋ฉฐ ์ผ๋ฐ˜์ ์œผ๋กœ ์ƒํ˜ธ ๋ฐฐ์ œ๋ฅผ ๋ณด์žฅํ•˜๋Š” ํŠน์ˆ˜ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•  ๋•Œ ์ปค๋„ ๊ฐœ๋ฐœ์ž๋งŒ ์‚ฌ์šฉํ•œ๋‹ค.

ํ•˜๋“œ์›จ์–ด ๋ช…๋ น์–ด

๊ฒฝ์Ÿ ์ƒํƒœ ์„น์…˜์—์„œ ๋‹ค๋ฃฌ ์ฆ๊ฐ ์—ฐ์‚ฐ์ž ๋‚ด๋ถ€ ๋™์ž‘์œผ๋กœ ์ธํ•ด ๋ฐœ์ƒํ•˜๋Š” ๋ฐ์ดํ„ฐ์˜ ์ผ๊ด€์„ฑ์„ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ•์ด๋‹ค. ํ•˜๋‚˜์˜ ๋ช…๋ น์–ด๊ฐ€ ์›์ž์ ์œผ๋กœ ์‹คํ–‰๋˜๊ณ  ์ธํ„ฐ๋ŸฝํŠธ๊ฐ€ ๋ฐœ์ƒํ•˜์ง€ ์•Š์•„, ๋ฐ์ดํ„ฐ์˜ ์ผ๊ด€์„ฑ์„ ๋ณด์žฅํ•  ์ˆ˜ ์žˆ๋‹ค. test_and_set()๊ณผ compare_and_swap() ๋ช…๋ น์–ด๋ฅผ ํ†ตํ•ด ์ด๋ฅผ ๋ณด์žฅํ•œ๋‹ค.

boolean test_and_set(boolean *target) {
	boolean rv = *target;
	*target = true;
	
	return rv;
}

int compare_and_swap(int *value, int expected, int new_value) {
	int temp = *value;
	
	if (*value == expected)
		*value = new_value;
		
	return temp;
}

์›์ž์  ๋ณ€์ˆ˜

์œ„์—์„œ ๋‹ค๋ฃฌ compare_and_swap() ๋ช…๋ น์–ด๋Š” ์ƒํ˜ธ ๋ฐฐ์ œ๋ฅผ ์ œ๊ณตํ•˜๊ธฐ ์œ„ํ•ด ์ง์ ‘ ์‚ฌ์šฉ๋˜์ง€ ์•Š๊ณ , ์ž„๊ณ„ ๊ตฌ์—ญ ๋ฌธ์ œ ํ•ด๊ฒฐํ•˜๋Š” ๋‹ค๋ฅธ ๋„๊ตฌ ๊ตฌ์ถ•์„ ์œ„ํ•œ ๊ธฐ๋ณธ ๊ตฌ์„ฑ์š”์†Œ๋กœ ์‚ฌ์šฉ๋œ๋‹ค. ๊ทธ๋Ÿฌํ•œ ๋„๊ตฌ ์ค‘ ํ•˜๋‚˜๊ฐ€ ์›์ž์  ๋ณ€์ˆ˜์ด๋‹ค. ์ •์ˆ˜ ๋ฐ boolean๊ณผ ๊ฐ™์€ ๊ธฐ๋ณธ ๋ฐ์ดํ„ฐ ์œ ํ˜•์— ๋Œ€ํ•œ ์›์ž์  ์—ฐ์‚ฐ์„ ์ œ๊ณตํ•˜๋ฉฐ, ๋‹จ์ผ ๋ณ€์ˆ˜์— ๋Œ€ํ•œ ๋ฐ์ดํ„ฐ ๊ฒฝ์Ÿ์— ๋Œ€ํ•ด ์ƒํ˜ธ ๋ฐฐ์ œ๋ฅผ ๋ณด์žฅํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋  ์ˆ˜ ์žˆ๋‹ค.

์†Œํ”„ํŠธ์›จ์–ด ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•

๋ฎคํ…์Šค ๋ฝ

๋ฎคํ…์Šค ๋ฝ์€ ์ž„๊ณ„๊ตฌ์—ญ์— ๋“ค์–ด๊ฐ€๊ธฐ ์ „ ํš๋“ํ•ด์•ผํ•˜๋Š” ๋ฝ์ด๋‹ค. ์ž„๊ณ„๊ตฌ์—ญ์— ๋“ค์–ด๊ฐ€๊ธฐ ์ „, acquire() ํ˜ธ์ถœ์„ ํ†ตํ•ด ๋ฎคํ…์Šค ๋ฝ์„ ํš๋“ํ•˜๊ณ  ๋‚˜์˜ฌ ๋•Œ release() ํ˜ธ์ถœ์„ ํ†ตํ•ด ๋ฝ์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค. acquire()๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ๋ถ€๋ถ„์„ acquire lock ์˜์—ญ, ์ž„๊ณ„ ๊ตฌ์—ญ์„ ๋‚˜์˜ค๋ฉด์„œ release()๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ๋ถ€๋ถ„์„ release lock ์˜์—ญ ๊ทธ๋ฆฌ๊ณ  ๋‚˜๋จธ์ง€ ์˜์—ญ์„ remainder section์ด๋ผ๊ณ  ํ•œ๋‹ค.

acquire() {
	while (!available)
		; /* busy wait */
	available = false;
}

release() {
	available = true;
}

์œ„ ๋‘ ํ•จ์ˆ˜๋Š” ์›์ž์ ์œผ๋กœ ์ˆ˜ํ–‰๋˜์–ด์•ผ ํ•˜๊ณ  compare_and_swap()๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ตฌํ˜„๋  ์ˆ˜ ์žˆ๋‹ค. acquire() ํ•จ์ˆ˜๋ฅผ ํ†ตํ•ด ๋ฝ์„ ํš๋“ํ•˜๊ณ ์ž ๋ฐ”์œ ๋Œ€๊ธฐ๋ฅผ ํ•œ๋‹ค. ๋ฐ˜๋ณต๋ฌธ์„ ํ†ตํ•ด ์ง€์†์ ์œผ๋กœ ๋Œ€๊ธฐ๋ฅผ ํ•˜๋ฉฐ, ๋‹ค๋ฅธ ํ”„๋กœ์„ธ์Šค๋“ค์˜ CPU ์ ์œ ๋ฅผ ๋ฐฉํ•ดํ•˜๊ณ  CPU ์‚ฌ์šฉ๋ฅ  ์ €ํ•˜๋กœ ์ด์–ด์ง€๊ธฐ ๋•Œ๋ฌธ์— ๋‹จ์ ์œผ๋กœ ์ž‘์šฉํ•œ๋‹ค.

๋ฐ”์œ ๋Œ€๊ธฐ๊ฐ€ ๊ผญ ๋‹จ์ ์œผ๋กœ ์ž‘์šฉํ•˜์ง€๋Š” ์•Š๋Š”๋‹ค. ๋งŒ์•ฝ, ๋ฐ”์œ ๋Œ€๊ธฐ๋ฅผ ํ•˜๋Š” ๊ณผ์ •์—์„œ ๋ฝ์„ ํš๋“ํ•œ๋‹ค๋ฉด ๋ณ„๋„์˜ ์ปจํ…์ŠคํŠธ ์Šค์œ„์นญ ์—†์ด CPU๋ฅผ ๋ฐ”๋กœ ์ ์œ ํ•  ์ˆ˜ ์žˆ๋‹ค. ๋ฐ”์œ ๋Œ€๊ธฐ๋ฅผ ํ•˜์ง€ ์•Š๋Š”๋‹ค๋ฉด ๋Œ€๊ธฐ ํ๋กœ ์˜ฎ๊ธฐ๋Š” ๊ณผ์ •์— ์ปจํ…์ŠคํŠธ ์Šค์œ„์นญ, ๋Œ€๊ธฐ ํ์—์„œ ๋ ˆ๋”” ํ๋กœ ์˜ฎ๊ธฐ๋Š” ๊ณผ์ •์—์„œ ์ปจํ…์Šค ์Šค์œ„์นญ ์ด 2๋ฒˆ์˜ ์ปจํ…์ŠคํŠธ ์Šค์œ„์นญ์ด ๋ฐœ์ƒํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์˜ค๋ฒ„ํ—ค๋“œ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค.

์„ธ๋งˆํฌ

์„ธ๋งˆํฌ๋Š” ์ •์ˆ˜ ๋ณ€์ˆ˜๋กœ์„œ, ์ดˆ๊ธฐํ™”๋ฅผ ์ œ์™ธํ•˜๊ณ ๋Š” ๋‹จ์ง€ ๋‘ ๊ฐœ์˜ ํ‘œ์ค€ ์›์ž์  ์—ฐ์‚ฐ์œผ๋กœ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋‹ค.

wait(S) {
	while (S <= 0)
		; // busy wait
		
	S--;
}

signal(S) {
	S++;
}

wait() ํ•จ์ˆ˜๋Š” ์„ธ๋งˆํฌ๊ฐ€ 0 ์ด์ƒ์ธ์ง€๋ฅผ ๊ฒ€์‚ฌํ•˜๊ณ , ์ฐธ์ผ ๊ฒฝ์šฐ ์„ธ๋งˆํฌ๋ฅผ 1 ๊ฐ์†Œ์‹œํ‚จ ํ›„ ๋ฝ์„ ํš๋“ํ•œ๋‹ค. signal() ํ•จ์ˆ˜๋Š” ๋ฝ์„ ๋ฐ˜ํ™˜ํ•˜๋Š” ๊ณผ์ •์—์„œ ์„ธ๋งˆํฌ๋ฅผ 1 ์ฆ๊ฐ€์‹œํ‚จ๋‹ค. ๋‘ ํ•จ์ˆ˜๋Š” ๋ชจ๋‘ ์›์ž์ ์œผ๋กœ ์‹คํ–‰๋˜์–ด์–ด์•ผ ํ•˜๋ฉฐ, ๋™์‹œ์— ๋™์ผํ•œ ์„ธ๋งˆํฌ ๊ฐ’์„ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์—†๋‹ค.

์„ธ๋งˆํฌ๋Š” ํฌ๊ฒŒ ๋‘ ๊ฐ€์ง€๋กœ ๊ตฌ๋ถ„ํ•œ๋‹ค.

  • ์นด์šดํŒ… ์„ธ๋งˆํฌ
    • ์„ธ๋งˆํฌ์˜ ๊ฐ’์˜ ์ œํ•œ์ด ์—†๋‹ค.
    • ์„ธ๋งˆํฌ์˜ ์ดˆ๊ธฐ ๊ฐ’์€ ์ž์›์˜ ๊ฐœ์ˆ˜๋กœ ์ดˆ๊ธฐํ™”๋œ๋‹ค.
  • ์ด์ง„ ์„ธ๋งˆํฌ
    • ์„ธ๋งˆํฌ์˜ ๊ฐ’์ด 0๊ณผ 1์‚ฌ์ด์˜ ๊ฐ’๋งŒ ๊ฐ€์ง„๋‹ค.
    • ๋ฎคํ…์Šค ๋ž‘๊ณผ ์œ ์‚ฌํ•˜๊ฒŒ ๋™์ž‘ํ•œ๋‹ค.

์„ธ๋งˆํฌ๋„ ๋ฎคํ…์Šค์™€ ๋™์ผํ•˜๊ฒŒ ์„ธ๋งˆํฌ์˜ ๊ฐ’์ด ์–‘์ˆ˜๊ฐ€ ๋  ๋•Œ๊นŒ์ง€ ๋Œ€๊ธฐํ•ด์•ผํ•˜๋Š” ๋ฌธ์ œ๊ฐ€ ์žˆ๋‹ค. ๋ฎคํ…์Šค์˜ ๋ฐ”์œ ๋Œ€๊ธฐ๋ฅผ ํ–ˆ์ง€๋งŒ, ์„ธ๋งˆํฌ์˜ ๊ฒฝ์šฐ ์œ„์˜ ๋‘ ์—ฐ์‚ฐ์„ ๋ณ€๊ฒฝํ•˜์—ฌ ๋ฐ”์œ ๋Œ€๊ธฐ๋ฅผ ์ง„ํ–‰ํ•˜์ง€ ์•Š์•„๋„ ๋œ๋‹ค.

  • wait()
    • ์„ธ๋งˆํฌ ๊ฐ’์ด ์–‘์ˆ˜๊ฐ€ ์•„๋‹Œ ๊ฒƒ์ด ๋ฐœ๊ฒฌ๋˜๋ฉด, ํ”„๋กœ์„ธ์Šค๋Š” ์ž์‹ ์„ ์ผ์‹œ ์ค‘์ง€ ์‹œํ‚จ๋‹ค.
    • ์ผ์‹œ ์ค‘์ง€ ์—ฐ์‚ฐ์€ ํ”„๋กœ์„ธ์Šค๋ฅผ ์„ธ๋งˆํฌ์— ์—ฐ๊ด€๋œ ๋Œ€๊ธฐ ํ์— ๋„ฃ๋Š”๋‹ค.
    • ํ”„๋กœ์„ธ์Šค์˜ ์ƒํƒœ๋ฅผ ๋Œ€๊ธฐ ์ƒํƒœ๋กœ ์ „ํ™˜ํ•œ๋‹ค.
    • ์ดํ›„ ์ œ์–ด๊ฐ€ CPU ์Šค์ผ€์ค„๋Ÿฌ๋กœ ๋„˜์–ด๊ฐ€๊ณ , ์Šค์ผ€์ค„๋Ÿฌ๋Š” ๋‹ค๋ฅธ ํ”„๋กœ์„ธ์Šค๋ฅผ ์‹คํ–‰ํ•˜๊ธฐ ์œ„ํ•ด ์„ ํƒํ•œ๋‹ค.
  • signal()
    • ์„ธ๋งˆํฌ๋ฅผ ๋ฐ˜๋‚ฉํ•˜๋Š” ํ”„๋กœ์„ธ์Šค๊ฐ€ wakeup() ์—ฐ์‚ฐ์„ ๋‚ด๋ถ€์ ์œผ๋กœ ํ˜ธ์ถœํ•˜์—ฌ ๋Œ€๊ธฐ์ค‘์ธ ํ”„๋กœ์„ธ์Šค๋ฅผ ์žฌ์‹œ์ž‘ํ•œ๋‹ค.
    • ํ•ด๋‹น ์—ฐ์‚ฐ์€ ํ”„๋กœ์„ธ์Šค์˜ ์ƒํƒœ๋ฅผ ๋Œ€๊ธฐ์ƒํƒœ์—์„œ ์ค€๋น„ ์™„๋ฃŒ ์ƒํƒœ๋กœ ๋ณ€๊ฒฝํ•œ๋‹ค.
    • ์ดํ›„, ํ”„๋กœ์„ธ์Šค๋Š” ๋ ˆ๋”” ํ์— ๋„ฃ์–ด์ง„๋‹ค.

์„ธ๋งˆํฌ๋Š” ํ•œ ๊ฐœ์˜ ์ •์ˆ˜์™€ ํ”„๋กœ์„ธ์Šค ๋ฆฌ์ŠคํŠธ list๋ฅผ ๊ฐ€์ง„๋‹ค. ํ”„๋กœ์„ธ์Šค๊ฐ€ ์„ธ๋งˆํฌ๋ฅผ ๊ธฐ๋‹ค๋ ค์•ผ ํ•œ๋‹ค๋ฉด, ์„ธ๋งˆํฌ์˜ ํ”„๋กœ์„ธ์Šค ๋ฆฌ์ŠคํŠธ์— ์ถ”๊ฐ€๋œ๋‹ค.

typedef struct {
	int value;
	struct process *list;
} semaphore;

wait(semaphore *S) {
	S->value--;
	if (S->value < 0) {
		add this process to S->list;
		sleep();
	}
}

signal(semaphore *S) {
	S->value++;
	if (S->value <= 0) {
		remove a process P from S->list;
		wakeup(P)
	}
}