在结构中创建绑定到 io_service 的线程

Creating thread bound to io_service inside a struct

我正在尝试创建一个包含 boost::thread 对象的简单结构。该结构(ApplicationPair)的构造函数需要传递一个 io_service 引用对象和一个方法;现在,为简单起见,我使用不带参数的 void 方法。 之后,使用 boost::bind.

创建线程

ApplicationPair.h

#ifndef APPLICATIONPAIR_H
#define APPLICATIONPAIR_H

#include <boost/thread.hpp>
#include <boost/asio.hpp>
#include <boost/function.hpp>
#include <boost/bind.hpp>
#include <cstdarg>

template<typename T>
struct ApplicationPair
{
    ApplicationPair(boost::asio::io_service& iSvc, boost::function<T()> func ) : _func(func)
    {
        iSvc.post(boost::bind(&ApplicationPair<T>::run, this));
        thr = boost::thread(boost::bind(&boost::asio::io_service::run, &iSvc));
    }
    ApplicationPair() = delete;
    ~ApplicationPair() { if (thr.joinable()) thr.join(); }

    void run(); 
    boost::thread thr;
    boost::function<T()> _func;
};

#endif

这里的想法是,我创建的每个新 ApplicationPair 对象在 io_service 上都有自己的线程,并且会在实例化时启动我想要的任何方法。

主要内容如下:

main.cpp

#include <boost/date_time/posix_time/posix_time.hpp>
#include <iostream>
#include <cstdio>

boost::asio::io_service iSvc;

void HelloWorld()
{
    std::cout << "HelloWorld\n";
}

template<typename T>
void ApplicationPair<T>::run()
{
    this->_func();
}
int main()
{
    ApplicationPair<void> p1(boost::ref(iSvc), HelloWorld);
    ApplicationPair<void> p2(boost::ref(iSvc), HelloWorld);
    ApplicationPair<void> p3(boost::ref(iSvc), HelloWorld);
    return 0;
} 

这就是我意识到事情进展得很糟糕的地方:我的预期输出是 3 "HelloWorld" 打印,但我只得到 2。 更奇怪的是,如果我 运行 调试,并按指令继续进一步的指令,HelloWorld 只打印一次!

老实说我一无所知,但我很清楚我没有完全理解多线程和 io_services 是如何工作的,Boost.org 上的文档根本没有帮助。

正如您怀疑的那样,您遗漏了有关 ASIO 的一些关键点。

您声明希望每个 ApplicationPair 在 io_service 上都有自己的线程。这实际上不是它的工作原理。在线程上调用 io_service.run() 后,该线程现在由 io_service 拥有。 io_service 将按其认为合适的方式安排活动。

把它想象成一个线程池,你 post 任务到 io_service 并且它将它们调度到池中。

另外,你应该看看 strands。这就像互斥体的 ASIO 版本。它的功能相似,但在概念上有所不同。boost::asio strand example

这在这里似乎并不重要,因为您不是在读取或写入变量,但是 std::cout 是您必须管理的全局资源。

我试图重新编写你的代码来给你举个例子,但这些差异将极大地改变它。而且我不确定您的最终目标是什么,因此很难提供示例。

还有一些不错的 youtube 视频: asio::strand asio basics