如何将信号连接到boost :: asio :: io_service在其他线程上发布工作时
How to connect signal to boost::asio::io_service when posting work on different thread?
我正在尝试使用Boost :: Lockfree队列来管理任务。这些任务检索数据,并将在工作线程上处理。数据检索后,应将信号发送到带有数据的主线程。在应用程序开始时,将工人线程产生,只是继续轮询队列。我是Boost :: Asio的新手,但是从我的研究来看,它似乎是线程之间发送信号的最佳机制。
我已经看过几个示例,特别是:
- 当boost :: asio :: io_service run方法块/unblocks 感到困惑
- boost asio帖子不起作用,io_service :: post后立即退出
这是我的代码:
#include "stdafx.h"
#include <thread>
#include <boost/asio.hpp>
#include <boost/bind.hpp>
#include <boost/lockfree/spsc_queue.hpp>
#include <boost/optional.hpp>
#include <boost/thread.hpp>
#include <boost/signals2.hpp>
typedef boost::signals2::signal<void(int)> signal_type;
class Task
{
public:
Task(int handle) : _handle(handle) {};
~Task() {};
virtual void Execute()
{
int result = _handle * 2;
}
private:
int _handle;
};
class Manager
{
public:
Manager()
{
_mainService = std::make_shared<boost::asio::io_service>();
_workerService = std::make_shared<boost::asio::io_service>();
_work = std::make_shared<boost::asio::io_service::work>(*_workerService);
_threadStarted = false;
Start();
};
~Manager() {};
void WorkerMain()
{
_workerService->poll();
}
void Start()
{
if (_threadStarted) return;
_workerThread = std::thread(&Manager::WorkerMain, this);
_threadStarted = true;
}
void Stop()
{
if (_threadStarted == false) return;
_mainService->stop();
_workerThread.join();
_mainService.reset();
}
void OnSignalFetchCompleted(int value)
{
int asdf = 0; //do stuff with data on main thread
}
void ProcessData(signal_type& signal)
{
int i = 0;
do
{
_queue.consume_one([&](std::shared_ptr<Task> task)
{
task->Execute();
//get data from task; send out signal with data
});
i++;
} while (i < 3);
}
void QueueData(int handle)
{
_signalFetchCompleted.connect(boost::bind(&Manager::OnSignalFetchCompleted, this, _1));
_workerService->post(boost::bind(&Manager::ProcessData, boost::ref(_signalFetchCompleted))); //!!does not compile
std::shared_ptr<Task> task = std::make_shared<Task>(handle);
_queue.push(task);
}
private:
boost::lockfree::spsc_queue<std::shared_ptr<Task>, boost::lockfree::capacity<1024>> _queue;
std::thread _workerThread;
bool _threadStarted;
std::shared_ptr<boost::asio::io_service> _mainService;
std::shared_ptr<boost::asio::io_service> _workerService;
std::shared_ptr<boost::asio::io_service::work> _work;
signal_type _signalFetchCompleted;
};
int _tmain(int argc, _TCHAR* argv[])
{
std::shared_ptr<Manager> mgr = std::make_shared<Manager>();
mgr->QueueData(5);
mgr->QueueData(10);
mgr->Stop();
return 0;
}
我在我无法解决的_workerService->帖子行上遇到了一个编译错误:
1>C:Boostboost/bind/mem_fn.hpp(333): error C2784: 'T *boost::get_pointer(const boost::scoped_ptr<T> &)' : could not deduce template argument for 'const boost::scoped_ptr<T> &' from 'const signal_type'
1> C:Boostboost/smart_ptr/scoped_ptr.hpp(150) : see declaration of 'boost::get_pointer'
1> C:Boostboost/bind/mem_fn.hpp(352) : see reference to function template instantiation 'R (__cdecl &boost::_mfi::dm<R,Manager>::call<const U>(U &,const void *) const)' being compiled
1> with
1> [
1> R=void (signal_type &)
1> , U=signal_type
1> ]
1> C:Boostboost/bind/mem_fn.hpp(352) : see reference to function template instantiation 'R (__cdecl &boost::_mfi::dm<R,Manager>::call<const U>(U &,const void *) const)' being compiled
1> with
1> [
1> R=void (signal_type &)
1> , U=signal_type
1> ]
1> C:Boostboost/bind/bind.hpp(243) : see reference to function template instantiation 'R (__cdecl &boost::_mfi::dm<R,Manager>::operator ()<T>(const U &) const)' being compiled
1> with
1> [
1> R=void (signal_type &)
1> , T=signal_type
1> , U=signal_type
1> ]
任何帮助解决此方法错误或对此方法的一般评论的任何帮助将不胜感激。谢谢。
鉴于新信息,问题是您的boost::bind
。您正在尝试调用成员函数而没有对象来调用它:您正在尝试调用ProcessData
,但是您尚未告诉绑定要调用哪个对象的绑定。您需要给它一个Manager
才能致电:
_workerService->post(boost::bind(&Manager::ProcessData, this, boost::ref(_signalFetchCompleted)));
这将在this
上调用ProcessData
,并传递给_signalFetchCompleted
编译器错误似乎是在谈论您构建boost::asio::io_service::work
对象,并且您传递了它不正确的参数:
error C2664: 'boost::asio::io_service::work::work(const boost::asio::io_service::work &)' : cannot convert argument 1 from 'std::shared_ptr<boost::asio::io_service>' to 'boost::asio::io_service &'
boost::asio::io_service::work
具有一个构造函数,该构造函数采用boost::asio::io_service&
和一个复制构造函数;但是,您将其传递给std::shared_ptr<boost::asio::io_service>
:
_work = std::make_shared<boost::asio::io_service::work>(_workerService);
在这里,_workerService
是std::shared_ptr<boost::asio::io_service>
,但是您需要boost::asio::io_service&
。尝试以下内容:
_work = std::make_shared<boost::asio::io_service::work>(*_workerService);
我认为BOOST :: ASIO不是您任务的最佳解决方案。您是否了解到有条件变量?它们更简单,可以用来实现您的目标。
- 类与私有变量的其他类之间的线程安全性
- 当我在其中一个线程执行中(在activemq-cpp中)捕获到特定值时,我如何终止/停止所有其他线程
- MESI协议和std::atomic-它是否确保所有写入立即对其他线程可见?
- 线程消息传递或更好:在"大师班"中访问其他班级的成员
- 锁定来自其他线程的类成员
- 使来自线程的数据流对所有其他线程都可读
- Qt信号和插槽如果从QRunnable或其他线程调用,则不起作用
- 当只有一个线程主要使用该对象而其他线程很少使用它时,如何最小化该对象的互斥锁锁定?
- 视频在唤醒其他线程时输入设备断开连接
- 如何从其他线程 winapi 获取消息
- 将抽象对象从主线程发送到其他线程
- 使用 std::condition_variable 触发其他线程.使用哪些互斥锁?
- 在其他线程中循环访问该concurrent_vector时调用 concurrency::concurrent_vect
- 生成线程并在运行时执行其他操作,只要它处于活动状态
- C++如何判断互斥体在阻塞其他线程时是否被单个线程不成比例地占用
- tbb::enumerable_thread_specific在其他线程库中工作吗
- 当其他线程正在编写线程安全时,我是否必须互斥读操作
- 无法从其他线程播放QMediaPlayer
- 无法修改其他线程中 ref 传递的值
- 其他线程堆栈上的可用内存无效