C++20 사용이 보편화되고 std::jthread를 사용하면 코드 양상이 어떻게 될 지 모르겠으나
회사도 그렇고 std::condition_variable을 잘못 사용하는 사례가 있어서 포스팅합니다.
필요없는 경우에도 쓰거나 왜 쓰는지 모르고 그냥 가져다 쓰는 것이 문제죠.
사실 아래 경우 제외하고 저는 condition_variable을 사용한 적이 없습니다.
4축 모션 시뮬레이터에서 4개의 모터를 각각 제어하는데 하나의 스레드가 모터 통신을 함으로써
4개의 스레드가 동기화, 즉 하나의 신호에 맞춰 같이 시작되는 경우입니다.
아주 잠깐은 훌륭한 코드였지만 자원 낭비가 심한 것은 사실이라
지금은 아두이노를 활용해서 아두이노가 4개의 모터를 한 번에 제어합니다.
(역시 깃허브에서 그렇게 구현한 데에는 다 이유가 있다는...)
여러 개의 스레드가 실행되고 신호를 기다리기 위해 당연 mutex가 필요하겠죠.
하지만 스레드 함수는 공유되기 때문에 std::shared_mutex를 사용합니다.
일반 mutex가 아니기에 당연 std::condition_variable_any를 사용하겠죠.
1 2 3 4 5 6 7 8 9 10 11 12 13 | void MotionController::motionThread(size_t index) { std::shared_lock<std::shared_mutex> locker(motionMutex); motionWaiter.wait(locker); int trigger = motionTriggers[index]; if (trigger >= 0) { motors[index]->trigger(motionTriggers[index]); motors[index]->normal(); } } | cs |
스레드는 아래와 같이 만들고 데이터를 준비한 다음
condition_variable의 notify 함수로 신호를 보내면 끝입니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | std::thread t[4]; for (size_t i = 0; i < motors.size(); i++) t[i] = std::thread(std::bind(&MotionController::motionThread, this, i)); Sleep(1); // blah blah motionWaiter.notify_all(); for (size_t i = 0; i < motors.size(); i++) t[i].join(); | cs |
간단하죠..?
이렇게 쉽게 동기화 할 수 있는데 참 어렵게 작성하시는 분들이 많아요.
그리고 불필요하게 condition_variable을 사용하지 않기를 바랍니다.. 😂
'코딩 > C++' 카테고리의 다른 글
C++ 디렉토리 목록 나열 - std::filesystem::directory_iterator (1) | 2018.02.22 |
---|