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

+ Recent posts