2009-02-19 48 views
4

我在Windows应用程序中使用pthreads。我注意到我的程序处于死锁状态 - 一个快速检查显示发生了以下情况:pthreads和CreateThread的死锁

线程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 [email protected]() 
#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 ?? 
+0

您在创建线程时是否使用了任何属性? – 2009-02-19 21:39:27

+0

不,完全没有属性(为属性传递NULL指针)。 – 2009-02-19 21:41:41

回答

1

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

你能尝试张贴其中锁定在线程2完成的代码片段,并在功能线3应该在开始?

编辑回应代码

你有没有解锁线程2互斥?你的踪迹显示它锁定了一个互斥锁,然后创建一个线程来完成所有这些工作,它试图对互斥锁上的锁定。线程2返回成功后,我猜测呢?此外,为什么你使用标志和睡眠,可能障碍或条件变量进程同步可能会更强大。

另一个说明,是b_thread_active标志标记为volatile吗?也许编译器正在缓存一些东西以防止它突然崩溃?