我正在尝试使用boost :: lockfree队列来管理任务 . 这些任务检索数据并在工作线程上处理 . 检索数据后,应将信号与数据一起发送到主线程 . 工作线程在应用程序启动时生成,并且只是继续轮询队列 . 我是Boost :: Asio的新手,但从我的研究来看,它似乎是在线程之间发送信号的最佳机制 .
我看了几个例子,特别是:
-
Confused when boost::asio::io_service run method blocks/unblocks
-
boost asio post not working , io_service::run exits right after 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-> Post行上遇到了一个我无法解决的编译错误:
1>C:\Boost\boost/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:\Boost\boost/smart_ptr/scoped_ptr.hpp(150) : see declaration of 'boost::get_pointer'
1> C:\Boost\boost/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:\Boost\boost/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:\Boost\boost/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> ]
任何帮助解决此编译错误或对此方法的一般性评论将不胜感激 . 谢谢 .
3 回答
根据新信息,问题出在您的
boost::bind
上 . 您正在尝试在没有对象的情况下调用成员函数来调用它:您正在尝试调用ProcessData
但是您没有告诉绑定您要在哪个对象上调用它 . 你需要给它一个Manager
来调用它:_workerService->post(boost::bind(&Manager::ProcessData, this, boost::ref(_signalFetchCompleted)));
这将在
this
上调用ProcessData
并传入对_signalFetchCompleted
的引用编译器错误似乎是在谈论你构造一个
boost::asio::io_service::work
对象,并且你传递的是不正确的参数:boost::asio::io_service::work有一个构造函数,它带有
boost::asio::io_service&
和一个复制构造函数;但是,你传递的是std::shared_ptr<boost::asio::io_service>
:这里,
_workerService
是std::shared_ptr<boost::asio::io_service>
,但你需要boost::asio::io_service&
. 请尝试以下方法:我认为boost :: asio不是你的任务的最佳解决方案 . 你读过条件变量吗?它们更简单,可用于实现您的目标 .