我第一次使用线程池,完成了Anthony Williams的“Concurrency In Action”一书。他提供了一个基本的线程池类,我正在尝试使用但不是实现 - 只是类。问题是我是模板和线程池的新手。这可能是一个简单的问题/答案,但我无法弄清楚。我有这个功能将作业提交到池中:
class SimpleThreadPool
{
public:
...
// -- Submit a task to the thread pool
template <typename FunctionType>
void submit(FunctionType f);
...
};
我试着打电话给它,但老实说不知道怎么样(尝试了几件不同的事情):
boost::interprocess::scoped_lock<std::mutex> lock(m_mtx_map);
for(const auto& elem : m_logger_map)
{
m_thread_pool->submit< std::function< void > >(elem.second->operator());
}
这里m_thread_pool是一个指向线程池的指针,地图包含(字符串,指针)对,其中指针指向一个日志对象,该对象具有operator()中的主要运行/处理方法。
我得到了: 错误:没有匹配的函数调用'SimpleThreadPool :: submit(&lt; unresolved overloaded function type&gt;)'
如何正确使用此提交功能?
谢谢!
更新-----
这是线程池类中的实现:
// -- Submit Method
/** void submit(FunctionType f)
* @desc : Submit a job (function pointer) to the pool
*/
template <typename FunctionType> void SimpleThreadPool::submit(FunctionType f)
{
m_q_work.push(std::function<void()>(f));
}
m_q_work是一个线程安全的队列。
// -- Launch a new worker thread
/** void m_worker_thread()
* @desc : Worker thread main method for getting tasks and executing
*/
void SimpleThreadPool::m_worker_thread()
{
while(!m_done)
{
std::function<void()> task;
if(m_q_work.try_pop(task))
{
task();
}
else
{
std::this_thread::yield();
}
}
}
我猜我可能需要根据我对以下回复的评论来改变实施。
答案 0 :(得分:0)
以下用g ++编译
#include <map>
#include <string>
#include <functional>
class SimpleThreadPool {
public:
template <typename FunctionType>
void submit(FunctionType f) { }
};
class Logger {
public:
void operator()() { }
};
int main(int argc,char **argv) {
std::map<std::string,Logger*> m_logger_map;
m_logger_map["one"]=new Logger();
SimpleThreadPool *m_thread_pool=new SimpleThreadPool();
for (const auto& elem: m_logger_map) {
m_thread_pool->submit<std::function< void() > >(*elem.second);
}
}
变更是:
1.- std::function< void() >
,而不是std::function<void>
(你的只有返回类型,但没有参数(注意我已经用空参数定义了operator())。
2.- *elem.second
作为提交的参数(而不是elem.second->operator()
)。请注意,函数对象(即定义了operator()
的类的对象)可以用作std::function
(请参阅std::function
reference中的示例)
我们可以使用Wrapper对象,而不是直接使用无法复制构造的Logger对象。此Wrapper对象包含对Logger类的引用。
我还将代码更改为使用shared_ptr,因为内存所有权变得更加复杂:
#include <map>
#include <string>
#include <functional>
#include <memory>
class SimpleThreadPool {
public:
template <typename FunctionType>
void submit(FunctionType f) { }
};
class Logger {
public:
Logger() { }
Logger(const Logger&) = delete; // Logger cannot be copied
void operator()() { }
};
template <typename T>
class Wrapper {
public:
Wrapper(const std::shared_ptr<T> &l):mWrapped(l) { } // Wraps a T reference
void operator()() {
(*mWrapped)(); // expected to be a function object
}
private:
std::shared_ptr<T> mWrapped;
};
int main(int argc,char **argv) {
// Need to change the definition of the map
// to contain shared_ptr.
std::map<std::string,std::shared_ptr<Logger> > m_logger_map;
m_logger_map["one"]=std::make_shared<Logger>();
SimpleThreadPool *m_thread_pool=new SimpleThreadPool();
for (const auto& elem: m_logger_map) {
// Create the Wrapper object from the reference we've
// obtained from the map.... The wrapper can be copied
// around, but the reference will not change.
std::function<void()> f=Wrapper<Logger>(elem.second);
m_thread_pool->submit<std::function< void() > >(f);
}
}