๐ฟ์ด์์ฒด์ (๋๊ธฐํ, ์ธ๋งํฌ์ด)
๐ฝ์ด์์ฒด์ (๋๊ธฐํ, ์ธ๋งํฌ์ด, ๋ฐ๋๋ฝ)
๋๊ธฐํ ์ด์(Synchronization) ์ด์
์ฌ์ง ์ถ์ฒ: https://solt.tistory.com/78
- ๋๊ธฐํ: ์์ ๋ค ์ฌ์ด์ ์คํ ์๊ธฐ๋ฅผ ๋ง์ถ๋ ๊ฒ
- ์ฌ๋ฌ ์ค๋ ๋๊ฐ ๋์ผํ ์์(๋ฐ์ดํฐ) ์ ๊ทผ์ ๋๊ธฐํ ์ด์ ๋ฐ์
- ๋์ผ ์์์ ์ฌ๋ฌ ์ค๋ ๋๊ฐ ๋์ ์์ ์, ๊ฐ ์ค๋ ๋ ๊ฒฐ๊ณผ์ ์ํฅ์ ์ค
๋๊ธฐํ ์ด์ ์์
import threading
g_count = 0
def thread_main():
global g_count
for i in range(1000000):
g_count = g_count + 1
threads = []
lock = threading.Lock()
for i in range(50):
th = threading.Thread(target= thread_main)
threads.append(th)
for th in threads:
th.start()
for th in threads:
th.join()
print('g_count = ', g_count)
- ํ์ด์ฌ์์ ์ฐ๋ ๋๋ฅผ ํต์ ํ๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ import ํ๋ค.
g_count
๋ผ๋ ์ ์ญ๋ณ์๋ฅผ ์ ์ธํด์ฃผ๊ณ- 1๋ถํฐ 100๋ง๊น์ง 1์ฉ ๋ํ๋ ๋ฐ๋ณต๋ฌธ ํจ์(
thread_main
)๋ฅผ ์ ์ํ๋ค - ํ๋ฆฐํธํด๋ณด๋ฉด 5์ฒ๋ง์ด ๋์ค์ง ์๊ณ ๋ค๋ฅธ ์ซ์๊ฐ ๋์จ๋ค.
์ด์์ฒด์ ๊ฐ ์ปจํ ์คํธ ์ค์์นญ์ํด์ ๋ฐฑ๋ง์ ๋ฐ๋ณต๋ฌธ์ด ์คํ๋๋ค๊ฐ ์ฐ๋ ๋๊ฐ ์ค๊ฐ์ ๋ฐ๋์ด์ ์๊ธฐ๋ ์ผ์ด๋ค.
ํด๊ฒฐ ๋ฐฉ๋ฒ
import threading
g_count = 0
def thread_main():
global g_count
lock.acquire()
for i in range(1000000):
g_count = g_count + 1
lock.release()
threads = []
lock =
for i in range(50):
th = threading.Thread(target= thread_main)
threads.append(th)
for th in threads:
th.start()
for th in threads:
th.join()
print('g_count = ', g_count)
-
lock.acquire()๋ฅผ ์ฌ์ฉํด์ ์ค๋ ๋๊ฐ ๋์์ ๋ฐ๋ณต๋ฌธ์ ์ ๊ทผํ ๋ ํ๊ฐ์ ์ค๋ ๋๋ง ์ ๊ทผํ๊ณ ๋๋จธ์ง๋ ๋ชป์ ๊ทผํ๊ฒ ํ๋ค.
-
๋ฐ๋ณต๋ฌธ์ ์ ๊ทผํ ์ค๋ ๋๊ฐ ๋์ค๋ฉด์ lock.release()ํจ์๋ฅผ ์คํํด์ ๋ค์ ์ค๋ ๋๊ฐ ๋ฐ๋ณต๋ฌธ์ ์ ๊ทผํ ์ ์๊ฒ ํ๋ค.
๋๊ธฐํ ์ด์ ํด๊ฒฐ ๋ฐฉ์
- Mutual exclusion(์ํธ ๋ฐฐ์ )
- ์ฐ๋ ๋๋ ํ๋ก์ธ์ค์ ๋ชจ๋ ๋ฐ์ดํฐ๋ฅผ ์ ๊ทผํ ์ ์์ผ๋ฏ๋ก,
- ์ฌ๋ฌ ์ค๋ ๋๊ฐ ๋ณ๊ฒฝํ๋ ๊ณต์ ๋ณ์์ ๋ํด Exclusive Access ํ์
- ์ด๋ ํ ์ค๋ ๋๊ฐ ๊ณต์ ๋ณ์๋ฅผ ๊ฐฑ์ ํ๋ ๋์ ๋ค๋ฅธ ์ค๋ ๋๊ฐ ๋์์ ์ ๊ทผํ์ง ๋ชปํ๋๋ก ๋ง๋๋ค.
Mutual exclusion(์ํธ ๋ฐฐ์ )
lock.acquire()
for i in range(1000000):
g_count = g_count + 1
lock.release()
- ๋ฐ๋ณต๋ฌธ์ด ์๊ณ์์ญ(critical section)์ด๊ณ
g_count += 1
์ด ์๊ณ์์(critical resource)์ด๋ค.
๋๊ธฐํ์ ์ธ๋งํฌ์ด
Mutex์ ์ธ๋งํฌ์ด (Semaphore)
- Critical Section(์๊ณ๊ตฌ์ญ)์ ๋ํ ์ ๊ทผ์ ๋ง๊ธฐ ์ํด LOCKING ๋งค์ปค๋์ฆ์ด ํ์
- Mutex(binary semaphore)
: ์๊ณ๊ตฌ์ญ์ ํ๋์ ์ค๋ ๋๋ง ๋ค์ด๊ฐ ์ ์์ - Semaphore
: ์๊ณ๊ตฌ์ญ์ ์ฌ๋ฌ ์ค๋ ๋๊ฐ ๋ค์ด๊ฐ ์ ์์
: counter๋ฅผ ๋์ด์ ๋์์ ๋ฆฌ์์ค์ ์ ๊ทผํ ์ ์๋ ํ์ฉ ๊ฐ๋ฅํ ์ค๋ ๋ ์๋ฅผ ์ ์ด
- Mutex(binary semaphore)
์ธ๋งํฌ์ด(Semaphore)
- P: ๊ฒ์ฌ (์๊ณ์์ญ์ ๋ค์ด๊ฐ ๋) -> lock.acquire()
- S๊ฐ์ด 1 ์ด์์ด๋ฉด, ์๊ณ ์์ญ ์ง์ ํ, S๊ฐ 1 ์ฐจ๊ฐ (S๊ฐ์ด 0์ด๋ฉด ๋๊ธฐ)
P(s): wait(S) {
while s <= 0 // ๋๊ธฐ
S--; // ๋ค๋ฅธ ํ๋ก์ธ์ค ์ ๊ทผ ์ ํ (1๊ฐ์)
}
- V: ์ฆ๊ฐ(์๊ณ์์ญ์์ ๋์ฌ ๋) -> lock.release()
- S๊ฐ์ 1๋ํ๊ณ , ์๊ณ ์์ญ์ ๋์ด
V(S): signal(S) {
s ++; // ๋ค๋ฅธ ํ๋ก์ธ์ค ์ ๊ทผ ํ์ฉ (1์ฆ๊ฐ)
}
- S: ์ธ๋งํฌ์ด ๊ฐ (์ด๊ธฐ ๊ฐ๋งํผ ์ฌ๋ฌ ํ๋ก์ธ์ค๊ฐ ๋์ ์๊ณ ์์ญ ์ ๊ทผ ๊ฐ๋ฅ)
์ธ๋งํฌ์ด(Semaphore)- ๋ฐ์ ๋๊ธฐ
- wait()์ S๊ฐ 0์ด๋ผ๋ฉด, ์๊ณ์์ญ์ ๋ค์ด๊ฐ๊ธฐ ์ํด, ๋ฐ๋ณต๋ฌธ ์ํ
- ๋ฐ์๋๊ธฐ, busy waiting -> ๋ฉ์ถค์ด ์๋ค. -> CPU์ ๋ถํ๋ฅผ ๊ฑธ๋ฆฌ๊ฒ ํจ
P(s): wait(S) {
while s <= 0 // ๋๊ธฐ
S--; // ๋ค๋ฅธ ํ๋ก์ธ์ค ์ ๊ทผ ์ ํ (1๊ฐ์)
}
์ธ๋งํฌ์ด(Semaphore) - ๋๊ธฐํ
- S๊ฐ ์์์ผ ๊ฒฝ์ฐ, ๋ฐ์ ๋๊ธฐ ๋์ , ๋๊ธฐํ์ ๋ฃ๋๋ค.
wait(S) {
S->count--;
if (S->count <= 0) {
add this process to S->queue; // ๋๊ธฐ
block() // ๋ธ๋ก, sleap()
}
}
- wakeup() ํจ์๋ฅผ ํตํด ๋๊ธฐํ์ ์๋ ํ๋ก์ธ์ค ์ฌ์คํ
signal(s) {
S->count++;
if (S->count >=1) {
remove a process P form S->queue;
wakeup(P) // ๊นจ์ฐ๊ธฐ
}
}
์ฐธ๊ณ : ์ฃผ์ ์ธ๋งํฌ์ด ํจ์(POSIX ์ธ๋งํฌ์ด)
- sem_open(): ์ธ๋งํฌ์ด๋ฅผ ์์ฑ
- sem_wait(): ์๊ณ์์ญ ์ ๊ทผ ์ , ์ธ๋งํฌ์ด๋ฅผ ์ ๊ทธ๊ณ , ์ธ๋งํฌ์ด๊ฐ ์ ๊ฒจ์๋ค๋ฉด, ํ๋ฆด ๋๊น์ง ๋๊ธฐ
- sem_post(): ๊ณต์ ์์์ ๋ํ ์ ๊ทผ์ด ๋๋ฌ์ ๋ ์ธ๋งํฌ์ด ์ ๊ธ์ ํด์ ํ๋ค.
Author And Source
์ด ๋ฌธ์ ์ ๊ดํ์ฌ(๐ฟ์ด์์ฒด์ (๋๊ธฐํ, ์ธ๋งํฌ์ด)), ์ฐ๋ฆฌ๋ ์ด๊ณณ์์ ๋ ๋ง์ ์๋ฃ๋ฅผ ๋ฐ๊ฒฌํ๊ณ ๋งํฌ๋ฅผ ํด๋ฆญํ์ฌ ๋ณด์๋ค https://velog.io/@sdk1926/์ด์์ฒด์ ๋๊ธฐํ-์ธ๋งํฌ์ด-๋ฐ๋๋ฝ์ ์ ๊ท์: ์์์ ์ ๋ณด๊ฐ ์์์ URL์ ํฌํจ๋์ด ์์ผ๋ฉฐ ์ ์๊ถ์ ์์์ ์์ ์ ๋๋ค.
์ฐ์ํ ๊ฐ๋ฐ์ ์ฝํ ์ธ ๋ฐ๊ฒฌ์ ์ ๋ (Collection and Share based on the CC Protocol.)
์ข์ ์นํ์ด์ง ์ฆ๊ฒจ์ฐพ๊ธฐ
๊ฐ๋ฐ์ ์ฐ์ ์ฌ์ดํธ ์์ง
๊ฐ๋ฐ์๊ฐ ์์์ผ ํ ํ์ ์ฌ์ดํธ 100์ ์ถ์ฒ ์ฐ๋ฆฌ๋ ๋น์ ์ ์ํด 100๊ฐ์ ์์ฃผ ์ฌ์ฉํ๋ ๊ฐ๋ฐ์ ํ์ต ์ฌ์ดํธ๋ฅผ ์ ๋ฆฌํ์ต๋๋ค