2011-05-23 49 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