2011-05-23 53 views
3

我想创建一个可以运行未知类的函数的线程池。我不希望创建非会员作为代理。 我设法创建了一个工作池& workerthread类和一个任务结构,所有这些都是模板。存储和后来调用未知类的成员函数

// ThreadPool.h 
/* Threadpool creates N WorkerThreads (each worker has a ptr to the creating pool), 
    these block until a task is ready then call ThreadPool::doTask() */ 
template<class T> 
struct Task { 
    Task() : func(0), inst(0) { } 

    Task(boost::function<void(T*)> function, T* instance) : func(0), inst(0) { 
     func = function; 
     inst = instance; 
    } 

    void operator()() { 
     Task::func(inst); 
    } 

    T* inst; 
    boost::function<void(T*)> func; 
}; 

template<class T> 
class ThreadPool { 
    template<class T> friend class WorkerThread; 
public: 

    void addTask(Task<T> task) { 
     ... // Some stuff 
    } 

    bool doTask() { 
     Task<T> task; 

     ... // Gets a task from std::queue 

     // Check the task actually exists! 
     if(task.func && task.inst) { 
      // Do the task 
      (task)(); 
     } 
    } 
private: 
    std::queue<Task<T>> mTasks; 
}; 

因为,这段代码的工作原理是,我确定了ThreadPool和Task的类。但我希望能够调用未知类类型的成员。我曾考虑过无效的ptr,但我找不到将其转换为有效实例ptr的方法。我也研究了boost :: mem_fun,但努力去真正去解决它。

我已经简要地阅读了关于C++ 0x的内容,并且从我的理解中,它应该能够更轻松地解决我的问题,但如果可能的话,我想在此之前解决此问题。

回答

3

为什么要使用T *而不仅仅是boost::function<void()>

这样你可以使用免费函数以及成员函数,并且可以简化代码。

一种在X类的实例成员的任务可以排队这样的:

poll.add(boost::bind(&X::member, x_instance, other_arguments)); 

在你的代码中没有管型和无模板。

更新:

使用boost :: function而不是您的Task类。然后,您只需要跟踪实例并根据需要调用它们。例如:

class TaskQueue { 
    std::deque<boost::function<void()> > m_tasks; 

public: 
    void add(boost::function<void()> const& f) { m_tasks.push_back(f); } 
    bool has_task() const { return !m_tasks.empty(); } 
    void do_task() { 
     m_tasks.front()(); 
     m_tasks.pop_front(); 
    } 
}; 

int example_enqueue(TaskQueue* tq) { 
    boost::shared_ptr<RandomClass> rc(new RandomClass); 
    tq->add(boost::bind(&RandomClass::method, rc, arg_1, arg_whatever)); 
} 

注意,通过将这种方法用升压:: shared_ptr的,你得到你的对象自动销毁当函数超出范围,如果它的最后一个引用。这使生活变得更容易。

+0

看起来这可能是我的解决方案,但我如何将其作为变量存储以备后用? – Mattyspatty 2011-05-24 12:47:49

+0

@Mattyspatty:查看更新的答案... – janm 2011-05-25 01:32:27

+0

这真是太好了,谢谢! – Mattyspatty 2011-05-25 10:50:10