문제
소스코드
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
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
|
#include<functional>
#include<condition_variable>
#include<mutex>
using namespace std;
class Foo {
public:
std::condition_variable cv;
int order;
std::mutex lock;
public:
Foo() {
order = 1;
}
void first(function<void()> printFirst) {
std::unique_lock<std::mutex> uniqueLock(lock);
cv.wait(uniqueLock, [&]() {return order == 1; });
// printFirst() outputs "first". Do not change or remove this line.
printFirst();
order = 2;
cv.notify_all();
}
void second(function<void()> printSecond) {
std::unique_lock<std::mutex> uniqueLock(lock);
cv.wait(uniqueLock, [&]() {return order == 2; });
// printSecond() outputs "second". Do not change or remove this line.
printSecond();
order = 3;
cv.notify_all();
}
void third(function<void()> printThird) {
std::unique_lock<std::mutex> uniqueLock(lock);
cv.wait(uniqueLock, [&]() {return order == 3; });
// printThird() outputs "third". Do not change or remove this line.
printThird();
}
};
|
후기
문제를 간단히 번역하면 1, 2, 3 숫자에 맞춰서 First(), Second(), Third() 함수가 출력되게 하면 된다.
Thread는 어느 Thread가 먼저 CPU Time(Time Qunanter)를 받을지 알 수 없기 때문에 동기화가 필요하다. 여기서는
Windows에 있는 WaitForSingleObject 의 사용이 불가능해서 C++11에 있는 Condition_variable 을 사용해서 동기화를 진행했다. w
Condition_variable 는 WaitforSingleObject 와 다르게 Unique_lock을 wait의 인자에 넣어줘야 한다. wait상태에서 해당 order가 본인인지 확인 후 본인이라면 함수를 실행 그 후 다시 모든 스레드를 깨워서 진행하도록 하였다. wait_once()를 하면 어떤 스레드가 깨어날지 알 수 없기 때문에 all을 사용했다.
나는 주로 Windows 함수를 사용했기 때문에 Condition_variable에 대해서 깊게는 알지 못한다. 이번기회에 공부를 할 수 있는 계기가 된거같고 이런 동시성 문제가 있다는게 신기하고 공부에 도움이 많이 될거같다.
출처 및 레퍼런스
문제 링크: (9) Print in Order - LeetCode