Boost 기반 뮤텍스 안전하게 사용하도록 하는 코드

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
class mutex_manager {
public:
    mutex_manager(const int& channelIndex) :
        channelIndex(channelIndex),
        deviceAddr("0.0.0.0")
    {}
 
    mutex_manager(const int& channelIndex, const std::string& deviceAddr) :
        channelIndex(channelIndex),
        deviceAddr(deviceAddr)
    {}
 
    //INFO: 같은 스레드에서 잠금 시도시 무시하고, 다른 스레드에서 잠금 시도 시 대기
    void get_mutex_lock(boost::mutex::scoped_try_lock& locker)
    {
        const boost::thread::id& currThreadId = boost::this_thread::get_id();
        boost::mutex::scoped_try_lock tempLock(mtx);
        //INFO: 뮤텍스 획득 실패
        if (!tempLock.owns_lock()) {
            //INFO: 같은 스레드에서 뮤텍스를 이미 사용중인 경우 무시
            if (mtxIndex == currThreadId) {
                printf("[%s] %s; channelIndex=%d. this thread already has profileMutex lock", deviceAddr.c_str(), __func__, channelIndex);
                return;
            }
 
            //INFO: 다른 스레드에서 요청한 경우 대기
            tempLock.lock();
        }
        mtxIndex = currThreadId;
 
        tempLock.swap(locker);
    }
 
private:
    //INFO: 이 뮤텍스는 get_mutex_lock() 함수를 통해서만 사용할 것
    boost::mutex mtx;
    //INFO: mtx를 현재 사용중인 스레드 ID를 보관
    boost::thread::id mtxIndex;
    //INFO: 채널 인덱스
    int channelIndex;
    //INFO: IP주소
    std::string deviceAddr;
};
cs