我正在尝试创建一个包含 boost::thread 对象的简单结构。这个结构(ApplicationPair)的构造函数需要传递一个io_service引用对象和一个方法;现在,为简单起见,我使用的是不带参数的 void 方法。
之后,使用 boost::bind 创建线程。
应用程序对.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 上拥有自己的线程,并在实例化时启动我想要的任何方法。
这是主要的:
主.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 将安排它认为合适的事件。
把它想象成一个线程池,你将任务发布到 io_service 并将它们安排到池中。
此外,您应该查看股线。这就像互斥体的 ASIO 版本。它的功能类似,但在概念上有所不同。 boost::asio strand example
这在这里可能看起来并不重要,因为您不是从变量读取或写入,但是 std::cout 是您必须管理的全局资源。
我试图修改你的代码来给你一个例子,但是这些差异会极大地改变它。而且我不确定您的最终目标是什么,因此很难提供示例。
这些也是一些不错的 youtube 视频:
asio::strand
asio basics
关于c++ - 在结构内创建绑定(bind)到 io_service 的线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61311808/