Windowsアプリケーションでpthreadを使用しています。プログラムがデッドロックしていることに気づきました。簡単に調べたところ、次のことが発生したことがわかりました。
スレッド1がスレッド2を生成しました。スレッド2がスレッド3を生成しました。スレッド2は、ロック解除されていないスレッド3からのミューテックスを待機していました。
そこで、gdbでデバッグし、3番目のスレッドをバックトレースすると次のようになりました。
Thread 3 (thread 3456.0x880):
#0 0x7c8106e9 in KERNEL32!CreateThread ()
from /cygdrive/c/WINDOWS/system32/kernel32.dll
Cannot access memory at address 0x131
どういうわけか、WindowsのCreateThread関数でスタック、デッドロックしました!明らかに、コードの実行を開始することさえできなかったとき、ミューテックスのロックを解除することはできませんでした。それでも、明らかにここでスタックしているという事実にもかかわらず、pthread_createはゼロ(成功)を返しました。
これを特に奇妙なものにしているのは、Linux上の同じアプリケーションにそのような問題がないことです。作成プロセス中にスレッドがハングする(!?)が、正しく作成されたかのように正常に戻る原因は、いったい何でしょうか。
編集:コードのリクエストに応じて、ここにいくつかのコードがあります(簡略化されています):
スレッドの作成:
if ( pthread_create( &h->lookahead->thread_handle, NULL, (void *)lookahead_thread, (void *)h->thread[h->param.i_threads] ) )
{
log( LOG_ERROR, "failed to create lookahead thread\n");
return ERROR;
}
while ( !h_lookahead->b_thread_active )
usleep(100);
return SUCCESS;
b_thread_activeが設定されるまで待機することに注意してください。したがって、何らかの形でb_thread_activeが設定されているため、呼び出されるスレッドは何かを実行する必要があります...
...これがlookahead_thread関数です:
void lookahead_thread( mainstruct *h )
{
h->lookahead->b_thread_active = 1;
while( !h->lookahead->b_exit_thread && h->lookahead->b_thread_active )
{
if ( synch_frame_list_get_size( &h->lookahead->next ) > delay )
_lookahead_slicetype_decide (h);
else
usleep(100); // Arbitrary number to keep thread from spinning
}
while ( synch_frame_list_get_size( &h->lookahead->next ) )
_lookahead_slicetype_decide (h);
h->lookahead->b_thread_active = 0;
}
lookahead_slicetype_decide(h); スレッドが行うことです。
ミューテックス、synch_frame_list_get_size:
int synch_frame_list_get_size( synch_frame_list_t *slist )
{
int fno = 0;
pthread_mutex_lock( &slist->mutex );
while (slist->list[fno]) fno++;
pthread_mutex_unlock( &slist->mutex );
return fno;
}
スレッド2のバックトレース:
Thread 2 (thread 332.0xf18):
#0 0x00478853 in pthread_mutex_lock ()
#1 0x004362e8 in synch_frame_list_get_size (slist=0x3ef3a8)
at common/frame.c:1078
#2 0x004399e0 in lookahead_thread (h=0xd33150)
at encoder/lookahead.c:288
#3 0x0047c5ed in ptw32_threadStart@4 ()
#4 0x77c3a3b0 in msvcrt!_endthreadex ()
from /cygdrive/c/WINDOWS/system32/msvcrt.dll
#5 0x7c80b713 in KERNEL32!GetModuleFileNameA ()
from /cygdrive/c/WINDOWS/system32/kernel32.dll
#6 0x00000000 in ??