2014-10-18 4 views
4

자체 루프에서 실행될 이벤트 루프 클래스를 만들고 std::functions과 같은 작업 추가를 지원하고 실행합니다. 이를 위해 , 여기에서 SafeQueue을 사용하고 있습니다 : https://stackoverflow.com/a/16075550/1069662스레드 안전 큐가있는 C++ 11 이벤트 루프

class EventLoop 
{ 
public: 
typedef std::function<void()> Task; 

EventLoop(){ stop=false; } 

void add_task(Task t) { queue.enqueue(t); } 

void start(); 

void stop() { stop = true; } 

private: 
    SafeQueue<Task> queue; 
    bool stop; 
}; 

void EventLoop::start() 
{ 
    while (!stop) { 
     Task t = queue.dequeue(); // Blocking call 
     if (!stop) { 
      t(); 
     } 
    }  

    cout << "Exit Loop"; 
} 

을 다음, 당신은 다음과 같이 사용합니다 :

EventLoop loop; 
std::thread t(&EventLoop::start, &loop); 

loop.add_task(myTask); 
// do smth else 

loop.stop(); 
t.join(); 

내 질문은 : 어떻게 정상적으로 스레드를 중지? 여기서 차단 대기열 호출 때문에 stop이 루프를 종료 할 수 없습니다.

+0

참고로 유휴/반복 목록도 있으면 도움이 될 것이라고 생각합니다. –

+0

'bool SafeQueue :: try_dequeue (Task & out, std :: chrono :: milliseconds timeout); 또는 이와 비슷한가? –

+0

가능하면 TBB의 [동시 대기열] (http://www.threadingbuildingblocks.org/docs/help/tbb_userguide/Concurrent_Queue_Classes.htm) 컨테이너를 간단한 블로킹 뮤텍스에 의존하는 대신 고성능으로 간주합니다. – sjdowling

답변

4

'포이즌 피임약'중지 작업 대기. 이는 대기열을 차단 해제하고 직접 스레드에 정리 및 종료를 요청하거나 소비자 스레드가 '중지'부울을 검사하도록 허용합니다.

응용 프로그램이 종료되기 전에 스레드/작업을 중지해야한다고 가정합니다. 나는 그걸로 벗어날 수 있다면, 보통 그렇게하려고하지 않습니다.

+0

thanks..so obvious – yandreiy

1

다른 접근 방법은 예외를 throw하는 작업을 대기열에 올려 놓는 것입니다. 코드에 대한 몇 가지 변경 :

class EventLoop { 

// ... 

    class stopexception {}; 

// ... 


    void stop() 
    { 
      add_task(
       // Boring function that throws a stopexception 
     ); 
    } 
}; 

void EventLoop::start() 
{ 
    try { 
     while (1) 
     { 
      Task t = queue.dequeue(); // Blocking call 
      t(); 
     } 
    } catch (const stopexception &e) 
    { 
     cout << "Exit Loop"; 
    } 
} 

그들에게 알레르기가있는 사람들을 위해 예외를 사용하지 않는 대안은, 단독 매개 변수로 EventLoop 참조를받는 함수로 작업을 재정의하는 것 및 stop()은 메인 루프에서 빠져 나오는 플래그를 설정하는 작업을 대기열에 넣습니다.