首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >安全中断C++11阻塞操作

安全中断C++11阻塞操作
EN

Stack Overflow用户
提问于 2016-02-08 09:36:32
回答 1查看 555关注 0票数 1

我有一个std::thread,它使用Boost的asio从串口读取:

代码语言:javascript
复制
std::atomic<bool> quit(false);

void serialThread()
{
    try
    {
        asio::io_service io;
        asio::serial_port port(io);

        port.open("COM9"); // Yeay no port enumeration support!

        port.set_option(asio::serial_port_base::baud_rate(9600));

        while (!quit)
        {
            asio::streambuf buf;
            asio::read_until(port, buf, "\n");

            auto it = asio::buffers_begin(buf.data());
            string line(it, it + buf.size());

            doStuffWithLine(line);
        }
    }
    catch (std::exception e)
    {
        cout << "Serial thread error: " << e.what() << endl;
    }
}

void SetupSignals()
{
    // Arrange it so that `quit = true;` happens when Ctrl-C is pressed.
}

int main(int argc, char *argv[])
{
    SetupSignals();

    thread st(serialThread);

    st.join();

    return 0;
}

当我按下Ctrl键时,我希望干净地退出线程,以便所有析构函数都被适当地调用(如果您不正确关闭资源,一些驱动程序会讨厌它)。

不幸的是,正如您所看到的,read_until()中的当前代码块,所以当您按下Ctrl时,在收到新的文本行之前不会发生任何事情。

一种解决方案是使用轮询,如下所示:

代码语言:javascript
复制
asio::async_read_until(port, buf, "\n", ...);
while (!quit)
    io.poll();

但我不想使用投票。它相当不雅致。我目前看到的唯一解决方案是在std::condition_variable quitOrIoFinished设置为true或读取完成时触发quit。但是我没有写asio,所以我不能给它一个条件变量来等待。

有没有干净的、理智的解决方案?在Go中,我只需要使用一个select在多个通道上等待,其中一个是退出通道。不过,我在C++中看不到类似的解决方案。

EN

回答 1

Stack Overflow用户

发布于 2016-02-08 09:44:47

使用asio::signal_set等待INT信号(control倾向于发送中断).

当它到达时,只需使用挂起的异步操作对IO对象调用cancel()。它们将返回error_code等于boost::asio::error::operation_aborted

现在,如果您有一个io_service::work对象,那么解构它,运行io_service::run()的所有线程就会返回,这样就可以加入它们了。

Note负责同步对IO对象的访问(例如,在它们上调用cancel()时),因为与io_servicestrand不同,这些对象不是线程安全的。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/35266314

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档