Является ли boost::io_service::post потокобезопасным?

Безопасно ли публиковать новые обработчики из обработчика? т.е. Могут ли потоки, вызвавшие io_service::run(), публиковать новые обработчики в тот же io_service?

Спасибо


person Johannes Gerer    schedule 16.06.2011    source источник


Ответы (2)


Это безопасно для обработчики сообщений из обработчика для одного экземпляра io_service в соответствии с документацией.

Безопасность потока

Отдельные объекты: безопасно.

Общие объекты: безопасно, за исключением того, что вызов reset() при наличии незавершенных вызовов run(), run_one(), poll() или poll_one() приводит к неопределенному поведению.

person Sam Miller    schedule 16.06.2011

Я думаю, это не потому, что следующий код не вернул 3000000, и я не видел ни мьютекс, синхронизирующий внутреннюю очередь io_service, ни очередь без блокировки.

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

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);
    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();
    workers.join_all();
  }

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

  char c; std::cin >> c;
  return 0;
}
person Fabio    schedule 02.06.2014
comment
Вы не должны останавливать службу. Он останавливается задолго до того, как workers закончил работу. - person NuPagadi; 03.05.2018