特定の関数が呼び出され、一度に複数のスレッドで実行されていないことを確認する必要があるプログラムを書いています。
ここでは、実際のプログラムで行われていることとまったく同じことを行う簡略化された疑似コードをいくつか書きました。
mutex _enqueue_mutex;
mutex _action_mutex;
queue _queue;
bool _executing_queue;
// called in multiple threads, possibly simultaneously
do_action() {
_enqueue_mutex.lock()
object o;
_queue.enqueue(o);
_enqueue_mutex.unlock();
execute_queue();
}
execute_queue() {
if (!executing_queue) {
_executing_queue = true;
enqueue_mutex.lock();
bool is_empty = _queue.isEmpty();
_enqueue_mutex.lock();
while (!is_empty) {
_action_mutex.lock();
_enqueue_mutex.lock();
object o = _queue.dequeue();
is_empty = _queue.isEmpty();
_enqueue_mutex.unlock();
// callback is called when "o" is done being used by "do_stuff_to_object_with_callback" also, this function doesn't block, it is executed on its own thread (hence the need for the callback to know when it's done)
do_stuff_to_object_with_callback(o, &some_callback);
}
_executing_queue = false;
}
}
some_callback() {
_action_mutex.unlock();
}
基本的には_action_mutex
、while ループでロックされ (lock
再度ロックできるようになるまでブロックしていると見なされます)、完了コールバックが呼び出されたときにロックが解除されることが期待されます (some_callback
上記のコードで)。
ただし、これは機能していないようです。がdo_action
同時に複数回呼び出されると、プログラムがロックアップします。while ループが同時に複数回実行されていることに関連している可能性があると思いますが、それがどのように当てはまるかわかりません。私のアプローチに何か問題がありますか?より良いアプローチはありますか?
ありがとう