带有线程安全队列的C ++ 11事件循环

时间:2014-10-18 16:21:18

标签: c++ multithreading c++11

我想创建一个将在其自己的线程上运行的事件循环类,支持将任务添加为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();

我的问题是:如何优雅地停止线程? 由于阻塞队列调用,此处不能退出循环。

2 个答案:

答案 0 :(得分:5)

排出毒药#39;停止任务。取消阻塞队列等待,并直接请求线程清理并退出或允许消费者线程检查“停止”。布尔值。

假设您需要在应用程序终止之前停止线程/任务。如果我能逃脱它,我通常会尽量不这样做。

答案 1 :(得分:1)

另一种方法:只排队引发异常的任务。对您的代码进行一些更改:

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()将设置的任务排队突破主循环的旗帜。