์คํฐ๋๋ฅผ ์ด์ํ๊ณ ์์ต๋๋ค. ํด๋น repository์ ๊ฐ๋ฉด ๋ ๋ง์ ์ ๋ณด๋ฅผ ๋ณด์ค ์ ์์ต๋๋ค!
ํนํ close ๋ PR์ ๋ณด์๋ฉด, ์ด๋ค ๋ถ๋ถ์ ๋ํด์ ๊ณ ๋ฏผํ๊ณ ์คํฐ๋์๋ค๊ณผ ์ด์ผ๊ธฐ๋๋ด๋์ง ๋ณด์ค ์ ์์ต๋๋ค
https://github.com/JulSaMo/CS-start
๐ ๋ค์ด๊ฐ๋ฉฐ
๐ธ Critical section (์๊ณ์์ญ) ์ด๋?
- ์ฌ๋ฌ ํ๋ก์ธ์ค๊ฐ ๋ฐ์ดํฐ๋ฅผ ๊ณต์ ํ๋ฉฐ ์ํ๋ ๋, ๊ฐ ํ๋ก์ธ์ค์์ ๊ณต์ ๋ฐ์ดํฐ๋ฅผ ์ ๊ทผํ๋ ํ๋ก๊ทธ๋จ ์ฝ๋ ๋ธ๋ก
- ์ฆ, ์ฌ๋ฌ ํ๋ก์ธ์ค๊ฐ ๋์ผ ์์์ ๋์์ ์ฐธ์กฐํ์ฌ ๊ฐ์ด ์ค์ผ๋ ์ํ ๊ฐ๋ฅ์ฑ์ด ์๋ ์์ญ!!
- ๊ณต์ ๋ฐ์ดํฐ๋ฅผ ์ฌ๋ฌ ํ๋ก์ธ์ค๊ฐ ๋์์ ์์ธ์คํ๋ฉด, ์๊ฐ์ ์ธ ์ฐจ์ด ๋ฑ์ผ๋ก ์๋ชป๋ ๊ฒฐ๊ณผ๋ฅผ ๋ผ ์ ์๊ธฐ ๋๋ฌธ์ ํ ํ๋ก์ธ์ค๊ฐ ๊ณต์ ๋ฐ์ดํฐ๋ฅผ ์์ธ์คํ๊ณ ์์ ๋ ๋ค๋ฅธ ํ๋ก์ธ์ค๋ค์ ์ ๋๋ก ๊ทธ ๋ฐ์ดํฐ๋ฅผ ์์ธ์คํ์ง ๋ชปํ๋๋ก ํด์ผํ๋ค. ๊ทธ๋์ ํ๋ก๊ทธ๋๋ฐ ์, ์ฑ๋ฅ ํฅ์์ ์ํด ์๊ณ ์์ญ์ ์ต์ํํ๋ ์ค๊ณ๋ฅผ ํด์ผํ๋ค.
๐ ์ธ๋งํฌ์ด (Semaphore)
- ํ๋ก์ธ์ค ๊ฐ ๋ฉ์์ง๋ฅผ ์ ์กํ๊ฑฐ๋ ๊ณต์ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ํตํด ํน์ ๋ฐ์ดํฐ๋ฅผ ๊ณต์ ํ๊ฒ ๋๋ ๊ฒฝ์ฐ ๋ฌธ์ ๊ฐ ๋ฐ์ํ ์ ์๋ค. (๋ฉ์์ง ์ ์ก์ด๋ ๊ณต์ ๋ฉ๋ชจ๋ฆฌ ๊ด๋ จ ํ๋ก์ธ์ค ๊ฐ ํต์ ์ฐธ๊ณ ๐ https://didu-story.tistory.com/313)
- ์ฆ, ๊ณต์ ๋ ์์์ ์ฌ๋ฌ ๊ฐ์ ํ๋ก์ธ์ค๊ฐ ๋์์ ์ ๊ทผํ๊ฒ ๋๋ฉด์ ๋ฌธ์ ๊ฐ ๋ฐ์ํ๋ ๊ฒ์ผ๋ก์จ, ๊ณต์ ๋ ์์ ์ ํ๋์ ๋ฐ์ดํฐ๋ ํ ๋ฒ์ ํ๋์ ํ๋ก์ธ์ค๋ง ์ ๊ทผํ ์ ์๋๋ก ์ ํํด๋์ด์ผ ํ๋ค.
- ์ด๋ฅผ ์ํ ๊ฒ์ด ๋ฐ๋ก '์ธ๋งํฌ์ด(Semaphore)' ์ด๋ค.
< ์ธ๋งํฌ์ด์ ๊ธฐ๋ณธ ์ง์์ ์๊ณ ๊ฐ์. >
- ๋์์ ํ๋์ ์์์ ์ ๊ทผ์ ๋ฐฉ์งํ๊ฒ ํ ์ ์๋ ๋น๋๊ธฐ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๋๋ฐ ์ฌ์ฉ๋๋ค.
- ์ฌ๋ฌ ํ๋ก์ธ์ค๊ฐ ๋ฐ์ดํฐ๋ฅผ ๊ณต์ ํ๋ฉด์ ์์ ์ ์ํํ ๋, ๋์์ ์ ๊ทผํ๋ฉด ์๋๋ ์์์ ๋์์ ์ ๊ทผํ ์ ์๋๋ก ๋ง๋ ํ๋๊ทธ ๊ธฐ๋ฅ์ ํ๋ค.
- Semaphore ๋ ๊ณต์ ์์์ ์ง์ ํ ์ ์๋ ํ์ฉ ๊ฐ์๋ฅผ ์๋ฏธํ๋ค. (0์ด ๋๋ฉด ํ๋ก์ธ์ค๋ค์ ๊ณต์ ์์์ ์ง์ ํ๋ ๊ฒ์ ๋ง๋ ๊ฒ)
๐ ์ธ๋งํฌ์ด (Semaphore) ์ฝ๊ฒ ์ดํดํ๊ธฐ
์๋ฒ์ ํ๋ฆฐํฐ๊ธฐ ๋ค์ฏ๋๊ฐ ๋ฌผ๋ ค์๋ค๊ณ ์น์. ์ฌ์ฉ์๊ฐ ํ๋ฆฐํธ๋ฅผ ์ฌ์ฉํ๋ ค๊ณ ์๋ฒ์ ์์ฒญ์ ๋ณด๋๋ค. ๊ทธ๋ฌ๋ฉด ๊ณต์ ์์ ์ฆ ํ๋ฆฐํฐ๊ฐ 5๊ฐ ์์ผ๋๊น ์ธ๋งํฌ์ด๋ ์ฒ์์ 5๋ก ์ค์ ๋๋ค. ๊ทธ๋ฆฌ๊ณ ํ๋ฆฐํฐ๋ฅผ ์ฌ์ฉ์๊ฐ ์ฌ์ฉํ ๋๋ง๋ค ํ๋์ฉ ์ธ๋งํฌ์ด๊ฐ ๊ฐ์๋๋ค. ๊ทธ๋ฌ๋ค๊ฐ ์ฌ์ฉํ ํ๋ฆฐํฐ๊ฐ ์์ด์ง๋ฉด ์ธ๋งํฌ์ด๋ ์กฐ๋ง๊ฐ 0์ด ๋๊ณ , ๋ค ์ฐ๊ณ ๋ฐํํ๋ฉด ์ธ๋งํฌ์ด๋ ๋ค์ +1 ์ฆ๊ฐํ๋ค. ์ด๋ฐ์์ผ๋ก ์๊ฐํ๋ฉด ๋๋ค!!
์ฆ, ์ธ๋งํฌ์ด๋ ๋จ์ํ ๋ณ์๋ผ๊ณ ์๊ฐํ๋ฉด ํธํ๋ค. ๊ณต์ ์์์ ๊ฐ์๋ฅผ ๋ํ๋ด๋ ๋ณ์
var semaphore = 2
// ์์
1 ์ํ
semaphore -= 1
// ์์
2 ์ํ
semaphore -= 1 // ํ์ฌ semaphore == 0
// ์์
3 ์ํ
// ํ์ฌ semaphore ๊ฐ 0์ด๊ธฐ ๋๋ฌธ์ ๋๊ธฐํ๋ค!
๐ ์ธ๋งํฌ์ด(Semaphore) ์ ๊ทผ ํจ์ : wait(), signal()
์ด๋ฅผ ์ํด ์ ๊ณต๋๋ ํจ์๊ฐ wait()๊ณผ signal() ์ด๋ค.
๐ธ wait()
- semaphore ์ ๊ฐ์ด ํ์ฌ 0๋ณด๋ค ํฌ๋ฉด ๊ฐ์ -1
- ์นด์ดํ ๊ฐ์ด 0์ด ๋๋ฉด ๊ฐ์ด ์ฆ๊ฐํ ๋๊น์ง ๋๊ธฐ
- ํ๋ก์ธ์ค๊ฐ ์์์ ์ฌ์ฉํ ํ ๋ '๊ธฐ๋ค๋ ค๋ผ!'๋ผ๋ ์๋ฏธ
๐ธ signal()
- semaphore ๊ฐ์ +1
- ํ๋ก์ธ์ค๊ฐ ์์์ ์ฌ์ฉํ๊ณ ๋์๋ค๋ '์ ํธ'๋ฅผ ์๋ฏธ
๐ Swift์์์ semaphore โจ
์ค์ํํธ์์๋ semaphore์ ์ญํ ์ ํ๋ DispatchSemaphore๊ฐ ์๋ค. (
์ฐธ๊ณ ๊ธ ๐ https://sujinnaljin.medium.com/ios-%EC%B0%A8%EA%B7%BC%EC%B0%A8%EA%B7%BC-%EC%8B%9C%EC%9E%91%ED%95%98%EB%8A%94-gcd-10-cb37c3e0cf13
1. ๋์ ์์ ๊ฐ์ ์ ํ
๊ณต์ ์์์ ์ ๊ทผ ๊ฐ๋ฅํ ์์ ์๋ฅผ 2๋ก ์ ํํ ์ฝ๋๋ฅผ ์์ฑํด๋ณด์.
let semaphore = DispatchSemaphore(value: 2)
์์ ๊ฐ์ด ๊ณต์ ์์์ ์ ๊ทผ ๊ฐ๋ฅํ (ํน์ ํ๋ฒ์ ์คํ ๊ฐ๋ฅํ) ์์ ์๋ฅผ ๋ช ์ํ๊ณ , ์๊ณ ๊ตฌ์ญ์ ๋ค์ด๊ฐ ๋์๋ semaphore์ wait()๋ฅผ, ๋์ฌ๋๋ signal()์ ํธ์ถํ๋ค. (wait๊ฐ -1, signal ์ด +1)
for i in 1...8 {
semaphore.wait() //semaphore ๊ฐ์
DispatchQueue.global().async() {
// ์๊ณ๊ตฌ์ญ (critical section)
print("๊ณต์ ์์ ์ ๊ทผ ์์ ๐น")
sleep(3)
print("๊ณต์ ์์ ์ ๊ทผ ์ข
๋ฃ ๐ฅ")
sleep(3)
semaphore.signal() //semaphore ์ฆ๊ฐ
}
}
์ด๋ ๊ฒ ํ๋ฉด ์ ๊ทผ ๊ฐ๋ฅํ ์์ ์๊ฐ 2๊ฐ ์ด๊ธฐ ๋๋ฌธ์ 2๊ฐ ์์์ ์์ ์ด ์๋ค๊ฐ๋ค ํ๋ค. (์์์์, ์ข ๋ก์ข ๋ฃ, ์์์์,,, )
2. ๋ ์ฐ๋ ๋์ ํน์ ์ด๋ฒคํธ ์๋ฃ ์ํ ๋๊ธฐํ
DispatchSemaphore๋ ๋ ๊ฐ์ง ๋ฐฉ์์ผ๋ก ์ฌ์ฉ๊ฐ๋ฅํ๋ค. ํ๋๋ ์์์ ๋ณธ ๋์ ์์ ๊ฐ์๋ฅผ ์ ํํ๋ ๊ฒ์ด๊ณ , ํ๋๋ ๋ ์ฐ๋ ๋๊ฐ ํน์ ์ด๋ฒคํธ์ ์๋ฃ ์ํ๋ฅผ ๋๊ธฐํํ๋ ๊ฒฝ์ฐ์ ์ ์ฉํ๋ค๋ ๊ฒ์ด๋ค.
Useful for when two threads need to reconcile the completion of a particular event.
์ด๊ฒ ๋ฌด์จ๋ง์ด๋๋ฉด
- ์ฐ๋ ๋ A๋ ์์ A ์คํ์ค
- ์ฐ๋ ๋ B๋ ์์ A๊ฐ ๋๋ ํ์ ๋ฌด์ธ๊ฐ๋ฅด ์ํํ๋ ค๊ณ ํจ.
์ด๋ฐ ์ํฉ์์ ์ฐ๋ ๋ B(์๋น์)๋ ์์๋ ์์ ์ ๊ธฐ๋ค๋ฆฌ๊ธฐ ์ํด์ wait๋ฅผ ํธ์ถํ๊ณ , ์ฐ๋ ๋ A(์์ฑ์)๋ ์์ ์ด ์ค๋น๋๋ฉด signal์ ํธ์ถํ๋ ์์ผ๋ก ์ฐ๋ ๋ B๊ฐ ์์ A์ ์๋ฃ ์ํ๋ฅผ ๋๊ธฐํํ ์ ์๋ค๋ ๊ฒ์ด๋ค.
์ด๋ฐ ๋ฐฉ์์ผ๋ก ์ฌ์ฉํ ๊ฒฝ์ฐ์๋ semaphore ์ด๊ธฐ๊ฐ์ 0์ผ๋ก ์ค์ ํ๋ค.
//DispatchSemaphore ์ด๊ธฐ๊ฐ 0์ผ๋ก ์ค์
let semaphore = DispatchSemaphore(value: 0)
print("task A๊ฐ ๋๋๊ธธ ๊ธฐ๋ค๋ฆผ")
// ๋ค๋ฅธ ์ค๋ ๋์์ task A ์คํ
DispatchQueue.global(qos: .background).async {
//task A
print("task A ์์!")
print("task A ์งํ์ค..")
print("task A ๋!")
//task A ๋๋ฌ๋ค๊ณ ์๋ ค์ค
semaphore.signal()
}
// task A ๋๋ ๋๊น์ง๋ value ๊ฐ 0์ด๋ผ, task A ์ข
๋ฃ๊น์ง block
semaphore.wait()
print("task A ์๋ฃ๋จ")
- task A๊ฐ ๋๋์ง ์์๋ฐ๋ฉด (์ฆ , signal()์ด ์คํ๋์ง ์์๋ค๋ฉด) semaphore.wait() ์ดํ์ ์์ ์ ์คํ๋์ง ์์ ๊ฒ์ด๋ค.
- ๊ทธ ์ ์ ์ธ๋งํฌ์ด ๊ฐ์ 0์ด๊ธฐ ๋๋ฌธ์
๐ ๋ค๋ฅธ ์์ ์ฝ๋
(์ฝ๋์ฐธ๊ณ ๐ https://onelife2live.tistory.com/5)
์๋ ์ฝ๋๋ ์ธ๋งํฌ์ด๋ฅผ ์ฌ์ฉํ ์์์ด๋ค. ์ด ์ฝ๋๋ฅผ ๋๋ฆฌ๋ฉด ๊ฒฐ๊ณผ๊ฐ์ด 3000์ด ๋์ค๋๋ฐ, ๋ง์ฝ์ ์ธ๋งํฌ์ด๋ฅผ ์ฌ์ฉํ์ง ์์๋ค๋ฉด 3000์ด ๋์ค์ง ์๊ณ ๋ ์์ ๊ฐ์ด ๋์ฌ ๊ฒ์ด๋ค. ๋ชจ๋ ํจ์๊ฐ ๋์์ ์ ๊ทผํ์ฌ ์ฐ์ฐํ๋ ค๊ณ ํ๊ธฐ ๋๋ฌธ์ด๋ค!
์ธ๋งํฌ์ด๋ฅผ ์ฌ์ฉํ๊ธฐ ๋๋ฌธ์ ์์
์ด ํ๊ฐ์ฉ ์งํ๋์์ ํ์ธํ ์ ์๋ค.
let queue = DispatchQueue(label: "Queue", attributes: .concurrent)
let group = DispatchGroup()
var result: Int = 0
// ๋ณดํต ๋ฆฌ์์ค ํ์ ๊ด๋ฆฌํ ๋๋ 0๋ณด๋ค ํฐ ๊ฐ์ value ํ๋ผ๋ฏธํฐ๋ก ์ ๋ฌํฉ๋๋ค.
// ์ฌ๋ฌ ์์
์ ํ๋์ฉ ์์๋๋ก ์คํํด์ผ ํ๋ค๋ฉด 1์ ์ ๋ฌํฉ๋๋ค.
let semaphore = DispatchSemaphore(value: 1)
queue.async(group: group) {
for _ in 1...1000 {
semaphore.wait() // 1 ๊ฐ์
result += 1
semaphore.signal() // 1 ์ฆ๊ฐ
}
}
queue.async(group: group) {
for _ in 1...1000 {
semaphore.wait()
result += 1
semaphore.signal()
}
}
queue.async(group: group) {
for _ in 1...1000 {
semaphore.wait()
result += 1
semaphore.signal()
}
}
group.notify(queue: DispatchQueue.main) {
print(result)
}
// 3000
https://ios-development.tistory.com/920
์ด ๊ธ๋ ์ฝ์ด๋ณด๋ฉด ์ข์ ๊ฒ ๊ฐ๋ค. UIKit์์ ์ด๋ป๊ฒ ์ฝ๋๋ฅผ ์์ฑํ๋์ง ์ฟ๋ณผ์์๋ค!
๐ ๋ฎคํ ์ค (Mutex)
๋์ ํ๋ก๊ทธ๋๋ฐ์์ ๊ณต์ ๋ถ๊ฐ๋ฅํ ์์์ ๋์ ์ฌ์ฉ์ ํผํ๊ธฐ ์ํด์ ์ฌ์ฉํ๋ ์๊ณ ๋ฆฌ์ฆ
- ์๊ณ๊ตฌ์ญ(critical section)์ ๊ฐ์ง ์ฐ๋ ๋๋ค์ ์คํ์๊ฐ (running time)์ด ์๋ก ๊ฒน์น์ง ์๊ณ ๊ฐ๊ฐ ๋จ๋ ์ผ๋ก ์คํ (์ํธ๋ฐฐ์ ) ๋๋๋ก ํ๋ ๊ธฐ์
- ํ ํ๋ก์ธ์ค์ ์ํด ์์ ๋ ์ ์๋ key๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ํ ์ํธ๋ฐฐ์ ๊ธฐ๋ฒ
- key์ ํด๋นํ๋ ์ด๋ค ๊ฐ์ฒด (object)๊ฐ ์์ผ๋ฉฐ, ์ด ๊ฐ์ฒด๋ฅผ ์์ ํ ์ฐ๋ ๋/ํ๋ก์ธ์ค ๋ง์ด ๊ณต์ ์์์ ์ ๊ทผํ ์ ์๋ค.
- ๋ค์ค ํ๋ก์ธ์ค๋ค์ ๊ณต์ ๋ฆฌ์์ค์ ๋ํ ์ ๊ทผ์ ์กฐ์จํ๊ธฐ ์ํด ๋๊ธฐํ (Synchronization) ๋๋ ๋ฝ(lock)์ ์ฌ์ฉํ๋ค.
- ์ฆ, ๋ฎคํ ์ค ๊ฐ์ฒด๋ฅผ ๋ ์ฐ๋ ๋๊ฐ ๋์์ ์ฌ์ฉํ ์ ์๋ค!
๐ ๋ฎคํ ์ค (Mutex) ์ฝ๊ฒ ์ดํดํ๊ธฐ
์ฐธ๊ณ ๐ https://worthpreading.tistory.com/90
๋ฎคํ
์ค๋ ํ์ฅ์ค์ด ํ๋ ๋ฟ์ด ์๋ ์๋น์ ๋น์ ํ ์ ์๋ค. ํ์ฅ์ค์ ๊ฐ๊ธฐ ์ํด์๋ ์นด์ดํฐ์์ ์ด์ ๋ฅผ ๋ฐ์๊ฐ์ผํ๋ค.
๋ด๊ฐ ๋ง์ฝ ํ์ฅ์ค์ ๊ฐ๋ ค๊ณ ํ๋๋ฐ, ์นด์ดํฐ์ ํค๊ฐ ์์ผ๋ฉด ํ์ฅ์ค์ ์ฌ๋์ด ์๋ค๋ ๋ป์ด๊ณ , ๋๋ ๊ทธ ์ด์ ๋ฅผ ์ด์ฉํด์ ํ์ฅ์ค์ ๊ฐ ์ ์๋ค.
๋ด๊ฐ ๋ง์ฝ ํ์ฅ์ค์ ์๋๋ฐ ์ํ ์ด๋ธ์ ์๋ ์ฌ๋๋ ํ์ฅ์ค์ ๊ฐ๊ณ ์ถ๋ค. ์ด ์ฌ๋์ ์๋ฌด๋ฆฌ ๊ธํ๋๋ผ๋, ํ์ฅ์ค ํค๊ฐ ์๊ธฐ ๋๋ฌธ์ ํ์ฅ์ค์ ๊ฐ์ง ๋ชปํ๋ค. ์ด์ฌ๋์ ๊ฒฐ๊ตญ ์นด์ดํฐ์์ ํค๊ฐ ์ฌ๋๊น์ง ๋๋ฅผ ๊ธฐ๋ค๋ ค์ผํ๋ค.
๋ ๋ด ์์ํ ์ด๋ธ์์ ํ์ฅ์ค์ด ๊ฐ๊ณ ์ถ๋ค. ์ด์ฌ๋๋ ๋ ๊ธฐ๋ค๋ ค์ผํ๋ค.
๋ด๊ฐ ํ์ฅ์ค์์ ๋์์ ํค๋ฅผ ๋๋ ค๋์๋ค. ์ด์ ๊ธฐ๋ค๋ฆฌ๋ ์ฌ๋ ์ค ๋งจ ์์ฌ๋์ด ํค๋ฅผ ๋ฐ์ ํ์ฅ์ค์ ๊ฐ ๊ฒ์ด๋ค.
์ด๋ ๊ฒ ๋์ํ๋ ๋ฐฉ์์ด ๋ฎคํ ์ค๊ฐ ๋์ํ๋ ๋ฐฉ์์ด๋ค. ํ์ฅ์ค์ ์ด์ฉํ๋ ์ฌ๋์ ํ๋ก์ธ์ค ํน์ ์ฐ๋ ๋์ด๋ฉฐ, ํ์ฅ์ค์ ๊ณต์ ์์, ํ์ฅ์ค ํค๋ ๊ณต์ ์์์ ์ ๊ทผํ๊ธฐ ์ํ ์ด๋ค ์ค๋ธ์ ํธ์ด๋ค!
๐ Swift์์์ Mutex โจ
์ค์ํํธ์์์ ๋ฎคํ ์ค๋, DispatchSemaphore ์ฒ๋ผ ๋ฐ๋ก ์ง์ํ์ง ์๋ ๊ฒ์ผ๋ก ๋ณด์ธ๋ค. ๊ทธ๋์ Mutex๋ฅผ Swift์์ ์ฌ์ฉํ๋๋ก ๋ฐด์น๋งํน(?)ํด์ ๋ง๋ ๊ธ์ ์ฒจ๋ถํ๋ค. ์ฝ์ด๋ณด๋ฉด ์์ฃผ ์ข์๋ฐ!!!!
https://medium.com/@sergebouts/swift-mutex-benchmark-b21ee293d9ad
๐ ๋ํ์ ์ธ ๋ฎคํ ์ค ์๊ณ ๋ฆฌ์ฆ
1. ๋ฐ์ปค (Dekker) ์๊ณ ๋ฆฌ์ฆ
flag ์ turn ๋ณ์๋ฅผ ํตํด ์๊ณ๊ตฌ์ญ์ ๋ค์ด๊ฐ ํ๋ก์ธ์ค/์ค๋ ๋๋ฅผ ๊ฒฐ์ ํ๋ ๋ฐฉ์
- flag : ํ๋ก์ธ์ค ์ค ๋๊ฐ ์๊ณ์์ญ์ ์ง์ ํ ๊ฒ์ด์ง ๋ํ๋ด๋ ๋ณ์
- turn : ๋๊ฐ ์๊ณ๊ตฌ์ญ์ ๋ค์ด๊ฐ ์ฐจ๋ก์ธ์ง ๋ํ๋ด๋ ๋ณ์
while(true) {
flag[i] = true; // ํ๋ก์ธ์ค i๊ฐ ์๊ณ ๊ตฌ์ญ ์ง์
์๋
while(flag[j]) { // ํ๋ก์ธ์ค j๊ฐ ํ์ฌ ์๊ณ ๊ตฌ์ญ์ ์๋์ง ํ์ธ
if(turn == j) { // j๊ฐ ์๊ณ ๊ตฌ์ญ ์ฌ์ฉ ์ค์ด๋ฉด
flag[i] = false; // ํ๋ก์ธ์ค i ์ง์
์ทจ์
while(turn == j); // turn์ด j์์ ๋ณ๊ฒฝ๋ ๋๊น์ง ๋๊ธฐ
flag[i] = true; // j turn์ด ๋๋๋ฉด ๋ค์ ์ง์
์๋
}
}
}
// ------- ์๊ณ ๊ตฌ์ญ ---------
turn = j; // ์๊ณ ๊ตฌ์ญ ์ฌ์ฉ ๋๋๋ฉด turn์ ๋๊น
flag[i] = false; // flag ๊ฐ์ false๋ก ๋ฐ๊ฟ ์๊ณ ๊ตฌ์ญ ์ฌ์ฉ ์๋ฃ๋ฅผ ์๋ฆผ
2. ํผํฐ์จ (peterson) ์๊ณ ๋ฆฌ์ฆ
๋ฐ์ปค์ ์ ์ฌํ์ง๋ง, ์๋๋ฐฉ ํ๋ก์ธ์ค/์ค๋ ๋์๊ฒ ์ง์ ๊ธฐํ๋ฅผ ์๋ณดํ๋ ๊ฒ์ ์ฐจ์ด๊ฐ ์๋ค.
while(true) {
flag[i] = true; // ํ๋ก์ธ์ค i๊ฐ ์๊ณ ๊ตฌ์ญ ์ง์
์๋
turn = j; // ๋ค๋ฅธ ํ๋ก์ธ์ค์๊ฒ ์ง์
๊ธฐํ ์๋ณด
while(flag[j] && turn == j) { // ๋ค๋ฅธ ํ๋ก์ธ์ค๊ฐ ์ง์
์๋ํ๋ฉด ๋๊ธฐ
}
}
// ------- ์๊ณ ๊ตฌ์ญ ---------
flag[i] = false; // flag ๊ฐ์ false๋ก ๋ฐ๊ฟ ์๊ณ ๊ตฌ์ญ ์ฌ์ฉ ์๋ฃ๋ฅผ ์๋ฆผ
3. ์ ๊ณผ์ (Bakery) ์๊ณ ๋ฆฌ์ฆ
์ฌ๋ฌ ํ๋ก์ธ์ค/์ค๋ ๋์ ๋ํ ์ฒ๋ฆฌ๊ฐ ๊ฐ๋ฅํ ์๊ณ ๋ฆฌ์ฆ. ๊ฐ์ฅ ์์ ์์ ๋ฒํธํ๋ฅผ ๊ฐ์ง๊ณ ์๋ ํ๋ก์ธ์ค๊ฐ ์๊ณ๊ตฌ์ญ์ ์ง์ ํ๋ค.
while(true) {
isReady[i] = true; // ๋ฒํธํ ๋ฐ์ ์ค๋น
number[i] = max(number[0~n-1]) + 1; // ํ์ฌ ์คํ ์ค์ธ ํ๋ก์ธ์ค ์ค์ ๊ฐ์ฅ ํฐ ๋ฒํธ ๋ฐฐ์
isReady[i] = false; // ๋ฒํธํ ์๋ น ์๋ฃ
for(j = 0; j < n; j++) { // ๋ชจ๋ ํ๋ก์ธ์ค ๋ฒํธํ ๋น๊ต
while(isReady[j]); // ๋น๊ต ํ๋ก์ธ์ค๊ฐ ๋ฒํธํ ๋ฐ์ ๋๊น์ง ๋๊ธฐ
while(number[j] && number[j] < number[i] && j < i);
// ํ๋ก์ธ์ค j๊ฐ ๋ฒํธํ ๊ฐ์ง๊ณ ์์ด์ผ ํจ
// ํ๋ก์ธ์ค j์ ๋ฒํธํ < ํ๋ก์ธ์ค i์ ๋ฒํธํ
}
}
// ------- ์๊ณ ๊ตฌ์ญ ---------
number[i] = 0; // ์๊ณ ๊ตฌ์ญ ์ฌ์ฉ ์ข
๋ฃ
๐ ๋ฎคํ ์ค์ ์ธ๋งํฌ์ด ์ฐจ์ด์
๋ฌด์จ๋ง์ธ์ง ์ ๋ชจ๋ฅด๊ฒ ๋ค.... ๊ณต๋ถํด๋ด์ผํ๋ค ใ
ใ
1๏ธโฃ ๋๊ธฐํ ๋์์ ๊ฐ์
- Mutex๋ ๋๊ธฐํ ๋์์ด only 1๊ฐ ์ผ ๋ ์ฌ์ฉํ๋ค.
- Semaphore๋ ๋๊ธฐํ ๋์์ด 1๊ฐ ์ด์์ผ ๋ ์ฌ์ฉํ๋ค.
2๏ธโฃ ์ธ๋งํฌ์ด๋ ๋ฎคํ ์ค๊ฐ ๋ ์ ์์ง๋ง, ๋ฎคํ ์ค๋ ์ธ๋งํฌ์ด๊ฐ ๋ ์ ์๋ค.
- Mutex๋ 0, 1๋ก ์ด๋ฃจ์ด์ง ์ด์ง ์ํ๋ฅผ ๊ฐ์ง๋ฏ๋ก, Binary Semaphore์ด๋ผ๊ณ ๋ ๋ถ๋ฆฐ๋ค.
3๏ธโฃ ์์ ์์ ์ ์ฐจ์ด๊ฐ ์๋ค.
- ๋ฎคํ
์ค๋ ์์ ์์ ๊ฐ ๊ฐ๋ฅํ๊ณ ์ฑ
์์ ๊ฐ๋๋ค. (์ํ๊ฐ 0๊ณผ 1๋ฟ์ด๋ฏ๋ก Lock ๊ฐ์ง ์ ์์)
- lock : ํ์ฌ ์๊ณ๊ตฌ์ญ์ ๋ค์ด๊ฐ ๊ถํ์ ์ป์ด์ด (๋ง์ฝ ๋ค๋ฅธ ์ฐ๋ ๋/ํ๋ก์ธ์ค๊ฐ ์๊ณ๊ตฌ์ญ ์ํ์ค์ด๋ฉด, ์ข ๋ฃํ ๋๊น์ง ๋๊ธฐํ๋ค.)
- unlock : ํ์ฌ ์๊ณ๊ตฌ์ญ์ ๋ชจ๋ ์ฌ์ฉํ์์ ์๋ฆผ. (๋๊ธฐ์ค์ธ ๋ค๋ฅธ ์ฐ๋ ๋/ํ๋ก์ธ์ค๊ฐ ์๊ณ๊ตฌ์ญ์ ์ง์ ํ ์ ์์)
- Semaphor ๋ ์์์ ์์ ํ์ง ๋ชปํ๋ค.
4๏ธโฃ ๋ฎคํ ์ค๋ ์์ ํ๊ณ ์๋ ์ฐ๋ ๋๋ง์ด ์ด ๋ฎคํ ์ค๋ฅผ ํด์ ํ ์ ์๋ค.
- ๋ฐ๋ฉด, semaphore๋ semaphore๋ฅผ ์์ ํ์ง ์๋ ์ฐ๋ ๋๊ฐ semaphore๋ฅผ ํด์ ํ ์ ์๋ค.
5๏ธโฃ Semaphore๋ ์์ฝ๋ฉ ๋ฒ์์ ๊ฑธ์ณ ์๊ณ , ํ์ผ ์์คํ ์์ ํ์ผ๋ก ์กด์ฌํ๋ค.
- ๋ฐ๋ฉด ๋ฎคํ ์ค๋, ํ๋ก์ธ์ค์ ๋ฒ์๋ฅผ ๊ฐ์ง๋ฉฐ, ํ๋ก์ธ์ค๊ฐ ์ข ๋ฃ๋ ๋ ์๋์ผ๋ก clean up ๋๋ค.
๋ฎคํ ์ค์ ์ธ๋งํฌ์ด ๋๋ค ๋ฐ์ดํฐ ๋ฌด๊ฒฐ์ฑ์ ๋ณด์ฅํ ์ ์์ผ๋ฉฐ ๋ชจ๋ ๊ต์ฐฉ ์ํ๋ฅผ ํด๊ฒฐํ์ง๋ ๋ชปํ๋ค๋ ํ๊ณ์ ์ด ์๋ค. ํ์ง๋ง ์ํธ ๋ฐฐ์ ๋ฅผ ์ํ ๊ธฐ๋ณธ์ ์ธ ๊ธฐ๋ฒ์ด๋ฉฐ, ์ฌ๊ธฐ์ ์กฐ๊ธ ๋ ๋ณต์กํ ๋งค์ปค๋์ฆ์ ์ ์ฉํด ๊ฐ์ ๋ ์ฑ๋ฅ์ ๊ฐ์ง ์ ์๋๋ก ํ๋๊ฒ์ด ๊ฐ์ฅ ์ค์ํ ํ๋ก๊ทธ๋๋ฐ ๋ฐฉ์์ด ๋ ๊ฒ์ด๋ค.
๐ Reference
https://onelife2live.tistory.com/5
https://jwprogramming.tistory.com/13
https://chelseashin.tistory.com/40
https://worthpreading.tistory.com/90