반응형
우선 Unsafe Region이 무엇인지 파악하기 위해 아래 링크를 참조해보자.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | #include <iostream> #include <cstdio> #include <queue> #include <thread> using namespace std; int ans; void func() { for (int i = 1; i <= 1000000; i++) ans++; } int main() { thread a(func); thread b(func); thread c(func); a.join(); b.join(); c.join(); cout << "최종 ans :: " << ans << endl; return 0; } // This source code Copyright belongs to Crocus // If you want to see more? click here >> | Crocus |
이 코드를 보면 ans가 Unsafe Region이 된다.
Unsafe Region이 될 수 밖에 없는 이유는
1. 만약 a스레드가 ans = 1이고 ans++를 할 때
2. 어셈블리 과정에서 ans + 1을 하려고 하는 순간 컨텍스트 스위칭을 당하게 되고
3. b스레드가 ans ++를 하여 ans = 2가 되고 컨텍스트 스위칭을 한 후
4. 다시 a가 ans를 +1할때는 1에서 +1을 하는 것이기에 ans = 3이 되지 않고 ans = 2가 되는 경우가 생긴다.
따라서 이러한 Unsafe Region을 제거하기 위해 뮤텍스를 이용해본다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | #include <iostream> #include <cstdio> #include <queue> #include <thread> #include <mutex> using namespace std; int ans; mutex myMutex; void func() { myMutex.lock(); for (int i = 1; i <= 1000000; i++) ans++; myMutex.unlock(); } int main() { thread a(func); thread b(func); thread c(func); a.join(); b.join(); c.join(); cout << "최종 ans :: " << ans << endl; return 0; } // This source code Copyright belongs to Crocus // If you want to see more? click here >> | Crocus |
이 과정에서 a가 myMutex.lock()를 하게 되면 b,c는 락이 걸려있기에 접근 할 수 없게되고, a가 끝나야 b 또는 c가 참여할 수 있게 된다.
따라서 mutex같은 것을 이용하여 비동기화를 동기화 시킬 수 있다.
(이때 join을 하는 이유는 main 스레드가 끝나면 프로그램이 종료되는데 join을 이용하면 스레드가 종료 될 때 까지 메인 스레드가 기다려주는 역할을 하게 된다.)
반응형
'Applied > Operating System(OS)' 카테고리의 다른 글
CPU,GPU, GPGPU (0) | 2018.09.30 |
---|---|
뮤텍스(Mutex), 세마포어(Semaphore), 모니터(Monitor) (0) | 2018.05.05 |
커널 레벨 스레드 vs 사용자 레벨 스레드 (0) | 2018.05.01 |
unique_lock를 이용한 Producer and Consumer (0) | 2018.02.27 |
OS 정의 그리고 I/O 정리 (0) | 2017.12.12 |