c++ - 在结构内创建绑定(bind)到 io_service 的线程

标签 c++ multithreading boost asio

我正在尝试创建一个包含 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/

相关文章:

c++ - 在 condition_variable::notify_all() 之后或之前解锁互斥量?

c# - 在启动时设置线程生命周期

c++ - 向进程边界发出线程信号

c# - 执行更改 UI 的方法时,是否必须在 DIspatcher 上调用 CheckAccess()?

c++ - 权重增加的枚举位集。 (C++ & Boost::dynamic_bitset)

boost - 需要在Visual Studio中编译缺少的 `detour 3.0`库

c++ - 对象从容器中删除自身

c++ - 如何在 C++ 中有效地将整个队列复制到 vector/数组?

c++ - Boost.Asio - 不执行所有处理程序

c++ - 通用迭代器/指针初始化