将任务提交到线程池实现问题

时间:2014-06-10 16:01:58

标签: c++ multithreading

我第一次使用线程池,完成了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();
        }
    }
}

我猜我可能需要根据我对以下回复的评论来改变实施。

1 个答案:

答案 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);
    }
}