実際、このコードはスレッドセーフではありません。ミューテックスは実際には何も保護していないため、暗黙の述語が競合状態に対して脆弱なままになっています。
このコードを見てください -- ミューテックスは何を保護していますか? 中断/再開状態を保護するものは何ですか?
void suspendMe()
{
pthread_mutex_lock(&m_SuspendMutex);
pthread_cond_wait(&m_ResumeCond, &m_SuspendMutex);
}
void resumeMe()
{
pthread_cond_signal(&m_ResumeCond);
pthread_mutex_unlock(&m_SuspendMutex);
}
正解です:
void suspendMe()
{ // tell the thread to suspend
pthread_mutex_lock(&m_SuspendMutex);
m_SuspendFlag = 1;
pthread_mutex_unlock(&m_SuspendMutex);
}
void resumeMe()
{ // tell the thread to resume
pthread_mutex_lock(&m_SuspendMutex);
m_SuspendFlag = 0;
phtread_cond_broadcast(&m_ResumeCond);
pthread_mutex_unlock(&m_SuspendMutex);
}
void checkSuspend()
{ // if suspended, suspend until resumed
pthread_mutex_lock(&m_SuspendMutex);
while (m_SuspendFlag != 0) pthread_cond_wait(&m_ResumeCond, &m_SuspendMutex);
pthread_mutex_unlock(&m_SuspendMutex);
}
スレッドはcheckSuspend
、中断できる安全なポイントで呼び出す必要があります。suspendMe
他のスレッドは、 およびを呼び出してresumeMe
、スレッドを一時停止/再開できます。
ミューテックスがm_SuspendFlag
変数を保護し、スレッドが中断するように指示され、再開するように指示され、保護下で中断するか中断したままにするかを確認し、コードをスレッドセーフにすることに注意してください。
ここで 2 つの別個のミューテックスを使用する方がよいのではないでしょうか?それとも、これが pthread を一時停止する正しい方法ですか??
2 つのミューテックスを使用すると、条件変数のポイント全体が無効になります。それらが機能する全体的なメカニズムは、待機する必要があるものがあるかどうかを確認し、待機中にロックを保持したり、ロックを解放して待機したりすることなく、アトミックに待機できることです。待機中にロックを保持している場合、他のスレッドはどのように状態を変更できますか? また、ロックを解除してから待機した場合、状態の変更を見逃した場合はどうなりますか?
ところで、スレッドを一時停止または再開することはほとんど意味がありません。外部からスレッドを一時停止する必要があると感じた場合、それは、実際にはやりたくないことを実行するようにスレッドをコーディングしたことを示しています。スレッドの一時停止または再開に関する質問は、多くの場合、スレッド プログラミングのメンタル モデルが正しくないことを示しています。スレッドは何かを待つ必要があるかもしれませんが、外部から「一時停止」されるべきではありません。なぜなら、スレッドは特定の作業を行うべきではないことを独自のコーディングによって既に知っているはずだからです。