2009-08-30 4 views
3

단어의 문제 :Boost.Thread에서 CEvent-like 동작

내 응용 프로그램에는 직렬 포트에서 읽는 클래스가 있습니다. COM 포트 처리에 Windows 기본 요소를 사용하며 비동기 읽기 스레드가 있습니다. Boost.Asio 및 Boost.Thread와 같은 Boost 라이브러리를 사용하여 Windows 기본 요소에서 변환하려고합니다.

Windows 포트에서 내 IO 스레드는 각각 메시지를 나타내는 여러 MFC CEvent 변수가 있습니다. 읽기 요청, 쓰기 요청, 읽기 완료, 쓰기 완료, IO 취소. WaitForMultipleObjects를 기다렸습니다.

내가 가진 문제는 Boost.Thread가 CEvent도 WaitForMultipleObjects도 유사하지 않은 것 같습니다. 가장 가까운 것은 이들을 버리고 이벤트를 부울 세트로 바꾸고 부울 변경시마다 호출되는 notify_all() 함수가있는 condition_variable을 사용하는 것입니다.

그러나 boost :: condition_variable은 CEvent와 하나의 중요한 방식이 다릅니다. CEvent가 대기하지 않는 동안 신호가 보내지면 다음 대기가 바로 성공합니다. boost :: condition_variable을 사용하면 대기 중이 아닌 경우 알림 함수가 무시됩니다.

즉, 플래그를 확인하고 알림을 잃을 수있는 condition_variable을 기다리는 사이에는 항상 간격이 있음을 의미합니다. 이로 인해 스레드가 중단됩니다.

누구든지이 문제의 해결책을 알고 있습니까? 코드에서

문제 :

// Old IO Thread 
CEvent msg_cancel; 
CEvent msg_read_req; 
CEvent msg_write_req; 
CEvent msg_read_comp; 
CEvent msg_write_comp; 

CEvent events[] = { 
    msg_cancel, 
    msg_read_req, 
    msg_write_req, 
    msg_read_comp, 
    msg_write_comp 
}; 

bool cancel = false; 

while (!cancel) 
{ 
    switch(WaitForMultipleObjects(5, events, false, INFINITE)) 
    { 
     case WAIT_OBJECT_0 : 
      // msg_cancel 
      cancel = true; 
      break; 

     ... 
    } 
} 

어떻게 Boost.Thread의에서 그를 에뮬레이트?

답변

3

말했듯이 Windows 스타일 이벤트를 닮기 위해서는 조건 변수와 부울 플래그가 필요합니다. 물론 여러 부울 플래그를 하나의 플래그로 결합하여 사용자의 필요를 충족시킬 수 있습니다.

그러나, 당신이 언급 한 문제 (조건 변수는 대기가 즉시 반환 것이다 active 상태를 결코) 보통 그런 식으로 해결 : 뮤텍스가 잠금을 해제 할 때까지 기다리는 두 번째 스레드를 가짐으로써

condition-variable 
mutex 

main-thread: 
    lock(mutex) { start condition-signaling-thread } 
    while(some predicate) { 
    condition-variable.wait(mutex) 
    do-stuff 
    } 

condition-signaling-thread: 
    loop:  
    lock(mutex) { 
     do-whatever 
    } 
    condition-variable.notify(); 

을 조건을 처리 할 스레드는 각 조건이 처리되도록 할 수 있습니다. (참고 : Java에서 notify() 메소드는 잠금 내에서 호출되어야합니다. 구현 세부 사항에 따라 C++에서 수행하면 성능이 저하 될 수 있지만, 프로그래머가 적어도 한 번 이상 수신자와의 상태 발화).

boost.thread가 windows 스타일 이벤트 (및 posix-semaphores, btw)를 제공하지 않는 이유는 이러한 프리미티브가 쉽게 망가뜨릴 수 있기 때문입니다. 응용 프로그램을 다른 플랫폼으로 이식 할 계획이 아니라면이 다른 스타일로 응용 프로그램을 적용하는 것이 그만한 가치가 없을 수도 있습니다.