코가손의 블로그

[네트워크/C++] Lock을 얻기 위한 대기방법(2) Event 본문

GameDev/NetworkProgramming

[네트워크/C++] Lock을 얻기 위한 대기방법(2) Event

Cogason 2022. 1. 3. 20:57
mutex m;
queue<int> q;

void Producer()
{
    while (true)
    {
        {
            unique_lock<mutex> lock(m);
            q.push_back(100);
        }
    
        this_thread::sleep_for(10000000ms);
    }
}

void Consumer()
{
    while (true)
    {
        unique_lock<mutex> lock(m);
        if (q.empty() == false)
        {
            int data = q.front();
            q.pop();
            cout << data << endl;
        }
    }
}

 

Producer와 Consumer관계와 같은 로직이 있다고 가정해보자

Producer가 하루에 1번 꼴로 데이터를 생산한다면

Consumer는 생성된 데이터가 있는지 하루종일 확인해야 되기 때문에 매우 비효율 적이다.

다음은 Event를 이용한 예제이다.

 

mutex m;
queue<int> q;
HANDLE handle;

void Producer()
{
    while (true)
    {
        {
            unique_lock<mutex> lock(m);
            q.push_back(100);
        }
        
        ::SetEvent(handle);
        this_thread::sleep_for(10000000ms);
    }
}

void Consumer()
{
    while (true)
    {
        ::WaitForSingleObject(handle, INFINITE);
        
        unique_lock<mutex> lock(m);
        if (q.empty() == false)
        {
            int data = q.front();
            q.pop();
            cout << data << endl;
        }
    }
}

int main()
{
    ::CreateEvent(NULL, FALSE, FALSE, NULL);
    
    thread t1(Producer);
    thread t2(Consumer);
    
    t1.join();
    t2.join();
    
    return 0;
}

 

::CreateEvent( IpEventAttributes, bManualReset, bInitialState, IpName);

IpEventAttributes : NULL 값 입력

bManualReset : FALSE는 자동, TRUE면 수동으로 signal을 non-signal 상태로 바꾸어 주어야함. 명령어는 ::ResetEvent(handle);

bInitialState : 초기 상태를 signal(TRUE)/non-signal(FALSE)로 결정

IpName : Event Object의 이름을 나타내는 포인터, 보통 NULL을 사용함

Comments