与pthreads和CreateThread的死锁

时间:2009-02-19 21:34:17

标签: windows multithreading pthreads deadlock

我在Windows应用程序中使用pthread。我注意到我的程序已经死锁 - 快速检查显示发生了以下情况:

线程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 ?? 

1 个答案:

答案 0 :(得分:1)

我会尝试在线程2和线程3中仔细检查你的互斥锁。使用标准的windows api为windows实现Pthreads;所以windows和linux版本之间会有细微差别。这是一个奇怪的问题,但是再一次,这在线程中发生了很多。

您是否可以尝试发布在线程2中完成锁定的代码片段,以及线程3应该从哪个函数开始?

编辑以响应代码

你有没有解开线程2中的互斥锁?您的跟踪显示它锁定了一个互斥锁,然后创建一个线程来完成所有尝试锁定互斥锁的工作。我猜测在线程2返回SUCESS之后呢?另外,为什么使用标志和休眠,也许屏障或条件变量可能更加健壮。

另外注意,b_thread_active标志是否标记为volatile?也许编译器正在缓存一些不允许它爆发的东西?