2012-01-28 13 views
4

私は現在、std::threadを使用して非常に単純なスレッドプールを作成しようとしています。 与えられたタスクが完了した後にスレッドを「生きている」状態に維持するために、私はstd::mutexをそれぞれに関連付けます。 truem_bAvailable設定したスレッドオブジェクトのために、ThreadPool検索をiを見つけるにはミューテックスロックは、要求されたのと同じ順序で行われますか?

// Thread loop 
while (1) 
{ 
    m_oMutex->lock(); 
    m_oMutex->unlock(); 
    m_bAvailable = false; 
    m_oTask(); 
    m_bAvailable = true; 
} 

// ThreadPool function which gives a task to a thread 
void runTask(boost::function<void()> oTask) 
{ 
    [...] 
    m_oThreads[i]->setTask(oTask); 
    m_oMutexes[i]->unlock(); // same mutex as thread's m_oMutex 
    m_oMutexes[i]->lock(); 
} 

原理は多少このようなものです。対応するミューテックスのロックを解除し、threadがそれをロックしてタスクを実行できるようにします。 threadは即座にロックを解除し、ThreadPoolは再びロックできるので、threadはタスクが完了すると停止します。

しかし、問題は、スレッドがスレッドに要求する順序でロックされることですか?つまり、threadmutexにロックを行った場合、ThreadPoolはロックを解除して再びロックします。最初にthreadにロックが渡されますか?そうでない場合は、それを保証する方法はありますか?

答えて

9

いいえ、あなたのスレッドループがあなたの例のようにロックを取得することは保証できません。条件付き変数を使用して、スリープ状態にしてロックを取るスレッドループに信号を送ります。 std::condition_variable::wait(...)を参照してください。

このトピックに関する一般的な情報は、http://en.wikipedia.org/wiki/Condition_variableです。 pthreadライブラリを使用していた場合、同等の呼び出しは "スレッドループ"でpthread_cond_wait、runTask関数ではpthread_cond_signalとなります。

+0

ありがとうございました。 'condition_variable'はそのトリックを完璧にするようです。しかし、私はhttp://en.cppreference.com/w/cpp/thread/condition_variable/waitでその例を試してみました。なぜ、最初のスレッドが 'std :: unique_lock'を' cv_m 'が(unique_lock'のコンストラクタで)mutexをロックする最初のものであるため、パラメータとしてブロックされます。 – Jukurrpa

+0

この例では、待機スレッドはおそらくすべてロックを取得し、信号を待つ間にロックを解放します。これらのスレッドが非同期的に実行されているため、非決定論的にロックを取得する順序。マルチスレッドの性質のために、それらが "待機"コールから目覚めた順序も未定義です。 1つのことは確かですが、それはそれらのスレッドのそれぞれが "cerr <<"を実行している間、mutex経由でコードに排他ロックを持つことです。 –