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について簡単に読んだことがあり、私が理解していることから、問題の解決が容易になるはずですが、可能であれば、その前にこれを解決したいと思います。

4

2 に答える 2

3

の代わりに T* を使用するのはなぜboost::function<void ()>ですか?

そうすれば、メンバー関数だけでなくフリー関数も使用でき、コードを簡素化できます。

クラス X のインスタンスのメンバーのタスクは、次のようにキューに入れることができます。

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

コードにキャストもテンプレートもありません。

アップデート:

Task クラスの代わりに boost::function を使用します。その後、インスタンスを追跡し、必要に応じて呼び出すだけです。例えば:

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

このメソッドを boost::shared_ptr と組み合わせることで、最後の参照である場合、関数がスコープ外になったときにオブジェクトが自動的に破棄されることに注意してください。それは人生をずっと楽にします。

于 2011-05-23T12:10:42.853 に答える
0

void* が機能します。あなたはただ強いをしなければなりませんreinterpret_cast。しかし、私はこのソリューションを使用しません。Boost には、ファンクター オブジェクトを作成する方法がたくさんあります: http://www.boost.org/doc/libs/1_46_1/doc/html/function.html

于 2011-05-23T12:04:13.777 に答える