私はマルチスレッド アプリケーション (std::thread を使用) とマネージャー (クラス ツリー) を使用して、異なるサブツリー (組み込み構造体サブツリー) でコードの一部を並列に実行しています。基本的な考え方は、SubTree の各インスタンスにはオブジェクトを格納する両端キューがあるということです。両端キューが空の場合、スレッドは新しい要素が両端キューに挿入されるか、終了基準に達するまで待機します。1 つのサブツリーでオブジェクトを生成し、それらを別のサブツリーの両端キューにプッシュできます。便宜上、すべての std::mutex、std::locks、および std::variable_condition は「locks」と呼ばれる構造体に格納されます。
クラス Tree は、次のメソッドを実行するいくつかのスレッドを作成します (最初の試行) :
void Tree::launch(SubTree & st, Locks & locks )
{
/* some code */
std::lock_guard<std::mutex> deque_lock(locks.deque_mutex_[st.id_]) ; // lock the access to the deque of subtree st
if (st.deque_.empty()) // check that the deque is still empty
{
// some threads are still running, wait for them to terminate
std::unique_lock<std::mutex> wait_lock(locks.restart_mutex_[st.id_]) ;
locks.restart_condition_[st.id_].wait(wait_lock) ;
}
/* some code */
}
問題は、スレッドが待機している間、「deque_lock」がまだロックされていることです。したがって、並行スレッドによって現在のスレッドの両端キューにオブジェクトを追加することはできません。
そこで、lock_guard を unique_lock に変更し、手動でロック/ロック解除を管理しました。
void launch(SubTree & st, Locks & locks )
{
/* some code */
std::unique_lock<std::mutex> deque_lock(locks.deque_mutex_[st.id_]) ; // lock the access to the deque of subtree st
if (st.deque_.empty()) // check that the deque is still empty
{
deque_lock.unlock() ; // unlock the access to the deque to enable the other threads to add objects
// DATA RACE : nothing must happen to the unprotected deque here !!!!!!
// some threads are still running, wait for them to terminate
std::unique_lock<std::mutex> wait_lock(locks.restart_mutex_[st.id_]) ;
locks.restart_condition_[st.id_].wait(wait_lock) ;
}
/* some code */
}
ここでの問題は、データ競合があることです。「待機」命令が「deque_lock.unlock()」命令の直後に実行されるようにしたいと思います。標準ライブラリでこのような重要な命令シーケンスを作成する方法を知っている人はいますか?
前もって感謝します。