我在 Windows 应用程序中使用 pthreads。我注意到我的程序陷入僵局——快速检查表明发生了以下情况:
线程 1 产生线程 2。线程 2 产生线程 3。线程 2 等待来自线程 3 的互斥锁,该互斥锁未解锁。
所以,我去gdb调试,回溯第三个线程时得到以下信息:
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 ??