[英]C++11 event loop with thread safe queue
我想創建一個事件循環類,它將在它自己的線程上運行,支持將任務添加為std::functions
並執行它們。 為此,我從這里使用SafeQueue: https ://stackoverflow.com/a/16075550/1069662
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'布爾值。
假設您需要在應用程序終止之前停止線程/任務。 如果我能逃脫它,我通常會盡量不這樣做。
另一種方法:只排隊拋出異常的任務。 對您的代碼進行一些更改:
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";
}
}
對於對它們過敏的人,不使用異常的替代方法是將Task重新定義為將EventLoop引用作為其唯一參數的函數,並且stop()將設置突發標記的任務排隊主循環。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.