デッドロックが発生していると思われるpthreadに問題があります。動作していると思ったブロッキングキューを作成しましたが、さらにテストを行った後、blocking_queueでブロックしている複数のスレッドをキャンセルしようとすると、デッドロックが発生するようです。
ブロッキングキューは非常に単純で、次のようになります。
template <class T> class Blocking_Queue
{
public:
Blocking_Queue()
{
pthread_mutex_init(&_lock, NULL);
pthread_cond_init(&_cond, NULL);
}
~Blocking_Queue()
{
pthread_mutex_destroy(&_lock);
pthread_cond_destroy(&_cond);
}
void put(T t)
{
pthread_mutex_lock(&_lock);
_queue.push(t);
pthread_cond_signal(&_cond);
pthread_mutex_unlock(&_lock);
}
T pull()
{
pthread_mutex_lock(&_lock);
while(_queue.empty())
{
pthread_cond_wait(&_cond, &_lock);
}
T t = _queue.front();
_queue.pop();
pthread_mutex_unlock(&_lock);
return t;
}
priavte:
std::queue<T> _queue;
pthread_cond_t _cond;
pthread_mutex_t _lock;
}
テストのために、このブロッキングキューをプルする4つのスレッドを作成しました。いくつかのprintステートメントをブロッキングキューに追加しました。各スレッドはpthread_cond_wait()メソッドに到達しています。ただし、各スレッドでpthread_cancel()とpthread_join()を呼び出そうとすると、プログラムがハングします。
また、これを1つのスレッドでテストしたところ、完全に機能します。
ドキュメントによると、pthread_cond_wait()はキャンセルポイントであるため、これらのスレッドでcancelを呼び出すと、実行が停止するはずです(これは、1つのスレッドでのみ機能します)。ただし、pthread_mutex_lockはキャンセルポイントではありません。pthread_cancel()が呼び出され、キャンセルされたスレッドが終了する前にミューテックスを取得してロックを解除し、次のスレッドがキャンセルされたときにミューテックスとデッドロックを取得できないという状況で何かが起こっている可能性がありますか?または、私が間違っていることは他にありますか。
どんなアドバイスも素敵でしょう。ありがとう :)