【问题标题】:Unblock synchronous read on boost::asio::serial_port在 boost::asio::serial_port 上取消阻止同步读取
【发布时间】:2012-02-08 19:24:32
【问题描述】:

我有一个boost::thread,它对boost::asio::serial_port 执行同步读取。当我销毁包含两者的类的实例时,我希望线程优雅地结束,即使它在读取调用中被阻塞。我该怎么做?

查看docs,我尝试了cancel,但它仅适用于异步读/写。然后我尝试了close,但我遇到了一个例外,这不是你可以恢复的那种。也许使用send_breaknative_handle? (这是 Windows,可移植性并不重要)

更新:我还尝试将stop io_service 传递给串行端口对象的构造函数,但read 并没有解除阻塞。

编辑:异常实际上是“可捕获的”,但我不想在析构函数中放置一个 try/catch 块,并且重构代码以在析构函数之外执行关闭过程会触发上层有很多变化。因此,如果某些 Boost 权威说没有其他方法,我只会选择这个解决方案。

【问题讨论】:

    标签: c++ windows boost serial-port boost-asio


    【解决方案1】:

    没有办法按照您的要求解除同步读取。

    有两种选择:

    • close/shutdown 端口并捕获引发的异常
    • 在您关闭应用程序时使用异步读取和cancel 它们

    当然,第一个不是一个好主意,因为您无法区分终止应用程序和错误。

    【讨论】:

    • 这就是为什么 Boost::Asio 不被称为 Boost::SioAndAsio :)
    • 您的意思是 boost::asio::serial_port 不是要同步读取或写入的吗?我采用同步读/写来避免轮询......如果他们允许我以这种方式读写,它工作得很好并且不会浪费 CPU 周期,他们应该提供一种优雅结束的方法。
    • 是的,几天前我也想做同样的事情。
    • 您是否在 Boost 邮件列表中询问并被告知没有其他方法?
    • 不,但我找到了一些指针,并阅读了大部分 asio 文档。看,这个问题:stackoverflow.com/questions/1856957/…
    【解决方案2】:

    在结束时,您说您遇到了一个“不是您可以从中恢复的类型”的异常。

    这是什么意思?

    解决方案似乎是捕获异常。为什么你不能这样做?

    如果您想区分错误和程序终止,请在关闭前设置程序终止标志。在异常处理程序( catch )中检查标志。如果设置,则作为程序终止处理,否则作为错误处理。

    您说您不希望在析构函数中放置 try/catch 块。这对我来说似乎是一种奇怪的偏见,但好吧还有其他方法。

    1. 您可以允许异常一直传播到围绕所有代码的最顶层 catch 块,并在那里处理它。 (当然,你确实有这样一个 try/catch 块来保护你的整个应用程序 :-)

    2. 其他方式也是可以的……但是boss刚刚路过

    【讨论】:

    • 我实际上忽略了异常并在调试器中点击了继续,但由于它发生在析构函数中,它让我太恼火了,在那里放了一个 try/catch 块。我可以重构我的代码以在析构函数之外执行此操作,但这会激起许多层析构函数调用并且会非常麻烦。我只会接受这是最后的解决方案。我相应地编辑了我的问题。
    • 关于析构函数中的异常,there are pitfalls。但我认为常见问题中提到的危险场景并不适用。此外,我在 boost-users 邮件列表中询问,他们告诉我要抓住 boost::asio::error::operation_aborted,这让我可以区分关闭和错误,我相信。我会试试这个,如果可行,我会接受你的回答。
    • 我试图捕捉 std::exception 并遇到运行时检查失败 #0(ESP 的值未保留或类似的东西)。我放弃了,决定使用 async_read and write + Boost Windows 事件等效于执行阻塞读写。
    猜你喜欢
    • 2010-10-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多