I'm using thread pools for the first time, working out of Anthony Williams' Concurrency In Action book. He provides a basic thread pool class that I'm trying to use but not an implementation - just the class. The issue is that I'm new to templates and thread-pools. This is probably a simple question/answer but I can't figure it out. I have this function to submit jobs to the pool:
class SimpleThreadPool
{
public:
...
// -- Submit a task to the thread pool
template <typename FunctionType>
void submit(FunctionType f);
...
};
I'm trying to call it but honestly don't know how (have tried a few different things):
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());
}
Here the m_thread_pool is a pointer to the thread pool and the map contains (string,pointer) pairs where the pointer points to a logging object which has it's main run/processing method in operator().
I'm getting a: error: no matching function call 'SimpleThreadPool::submit(< unresolved overloaded function type >)'
How do I correctly use this submit function?
Thank you!
UPDATE -----
Here's the implementation in the thread pool class:
// -- 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 is a thread-safe Queue.
// -- 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();
}
}
}
I'm guessing I probably need to change the implementation based on my comment to the response below.
The following compiled in 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);
}
}
Changes are:
1.- std::function< void() >
, instead of std::function<void>
(yours only had the return type, but not the parameters (note that I've defined the operator() with empty parameters).
2.- *elem.second
as the argument to submit (instead of elem.second->operator()
). Note that a function object (ie an object of class with an operator()
defined) can be used as a std::function
(refer to the examples in the std::function
reference )
Instead of using directly the Logger object that cannot be copy-constructed, we can use a Wrapper object. This Wrapper object contains a reference to the Logger class.
I've also changed the code to use shared_ptr, because memory ownership becomes more complex:
#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);
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.