调用 executor_work_guard::reset 后io_service不停止

io_service not stopping after calling executor_work_guard::reset

提问人:user3703826 提问时间:10/11/2023 最后编辑:seheuser3703826 更新时间:10/11/2023 访问量:74

问:

我是提升 asio 的新手,并在调用 work_gaurd 重置函数后尝试获得干净的退出。以下是我试图让它工作的代码。但是,我无法打印“IO Context Stopped”

我在这里错过了什么吗?

int main() {
  boost::asio::io_context ioContext;                                                                                                                                                                                                                       
  auto work = boost::asio::make_work_guard(ioContext);                                                                                                                                                                                                     
  ioContext.post([]() {                                                                                                                                                                                                                                    
    std::cout << "Task executed on thread: " << std::this_thread::get_id()                                                                                                                                                                                 
              << std::endl;                                                                                                                                                                                                                                
  });                                                                                                                                                                                                                                                      
  std::thread ioThread([&ioContext]() { ioContext.run(); });                                                                                                                                                                                               
  std::this_thread::sleep_for(std::chrono::seconds(2));                                                                                                                                                                                                    
  work.reset();                                                                                                                                                                                                                                            
  //! ioContext.stop();                                                                                                                                                                                                                                    
  ioThread.join();                                                                                                                                                                                                                                         
  std::cout << "IO context stopped." << std::endl;                                                                                                                                                                                                         
  return 0;                                                                                                                                                                                                                                                
}
C++ Boost boost-ASIO 共享 PTR

评论


答:

0赞 sehe 10/11/2023 #1

代码很好(即使这里的工作卫士是完全多余的):

在 Coliru 上直播

#include <boost/asio.hpp>
#include <iostream>
using namespace std::chrono_literals;

int main() {
    boost::asio::io_context ioContext;

    auto work = make_work_guard(ioContext);
    post(ioContext, [] { std::cout << "Task executed on thread" << std::endl; });

    std::thread ioThread([&] { ioContext.run(); });

    std::this_thread::sleep_for(2s);
    work.reset();

    ioThread.join();
    std::cout << "IO context stopped." << std::endl;
}

测试对象

g++ -std=c++20 -O2 -Wall -pedantic -pthread main.cpp && time ./a.out

印刷品,例如

Task executed on thread
IO context stopped.

real    0m2,004s
user    0m0,000s
sys     0m0,004s

奖金

请注意,没有防护装置的结果是一样的。更简单的是使用,这意味着一个工作卫士:thread_pool

在 Coliru 上直播

int main() {
    {
        boost::asio::thread_pool ioContext(1);
        post(ioContext, [] { std::cout << "Task executed on thread" << std::endl; });
        std::this_thread::sleep_for(2s);
        // ioContext.join();
    }

    std::cout << "IO context stopped." << std::endl;
}

评论

0赞 sehe 10/11/2023
您可以编辑现场演示以找到您与众不同的东西。例如,当发布的任务阻塞时,会导致所有内容被阻塞: coliru.stacked-crooked.com/a/4e495f8eaa8df868
0赞 user3703826 10/12/2023
如果我删除,那么你的代码也会卡住。睡觉有什么原因吗std::this_thread::sleep_for(2s);
0赞 sehe 10/12/2023
那是你的睡眠。我以为你希望它代表别的东西。不过让我检查一下重现
0赞 sehe 10/12/2023
不,这不会重现,您也可以自己验证这一点 - 这就是为什么我建议编辑在线复制器以排除您未显示的其他代码/情况:coliru.stacked-crooked.com/a/56235141fa7bb77b 甚至 coliru.stacked-crooked.com/a/ebe2337e3b3f8a9f
1赞 user3703826 10/14/2023
我发现,当我启用BOOST_ASIO_DISABLE_THREADS标志时,程序将永远卡住,否则它会正常工作。上面有什么原因停止执行吗?@sehe