boost::io_service::post 线程安全吗?

问题描述 投票:0回答:2

从处理程序中发布新处理程序是线程安全的吗? IE。调用

io_service::run()
的线程可以将新的处理程序发布到同一个 io_service 吗?

谢谢

c++ thread-safety boost-asio boost-thread
2个回答
10
投票

根据文档,从 io_service 的单个实例的处理程序中发布处理程序是

安全

线程安全

不同的对象:安全。

共享对象:安全,除了在调用reset()时 还有未完成的run()、run_one()、 poll() 或 poll_one() 调用结果 未定义的行为。


0
投票

我对这篇文章进行了大量编辑,请注意:原始代码有一些细微的错误,因此它似乎反驳了 ASIO 的线程安全性。我已经标记了执行后获得正确计数器 3000000 所需的更正。查看编辑历史记录以查看所做的代码更改。最重要的更新是将

service.stop()
(这会使部分已发布的工作未完成)更改为
guard.reset()
,这允许
io_service
在所有工作完成后退出。

我选择编辑而不是发布不同的答案,因为大部分代码仍然来自原作者。由于后者在很多很多年前才活跃,而且关于他的错误的评论也很早以前就已经发表了,因此等待更长时间是没有意义的。

#include <boost/asio/io_service.hpp>
#include <boost/asio/executor_work_guard.hpp>
#include <boost/thread.hpp>
#include <boost/thread/detail/thread_group.hpp>
#include <memory>
#include <iostream>

void postInc(boost::asio::io_service *service, std::atomic_int *counter) {
  for(int i = 0; i < 100000; i++) service->post([counter] { (*counter)++; });
}

int main(int argc, char **argv)
{
  std::atomic_int counter(0);
  
  {
    boost::asio::io_service service;
    // boost::asio::io_service::work working(service);
    auto guard = make_work_guard(service);
    boost::thread_group workers;
    
    for(size_t i = 0; i < 10;++i)     workers.create_thread(boost::bind(&boost::asio::io_service::run, &service));

    boost::thread_group producers;
    for (int it = 0; it < 30; it++)
    {
      producers.add_thread(new boost::thread(boost::bind(postInc,&service,&counter)));
    }

    producers.join_all();
    std::cout << "producers ended" << std::endl;

    // service.stop();
    guard.reset();
    workers.join_all();
  }

  std::cout << counter.load() << std::endl;

  return 0;
}
© www.soinside.com 2019 - 2024. All rights reserved.