2011-11-30 86 views
8

OS是Linux,使用pthreadspthreads,我怎么知道进程内的另一个线程没有在等待?

我有两个永久运行的工作线程,直到stop变量的值为true,并且线程正常终止。而不是忙于等待两个线程调用pthread_cond_wait,直到信号通知新任务。该系统运作良好。

它被要求创建一个“info”线程来打印一些调试信息。信息线程将尝试每30秒读取和打印信息。部分信息,我想成为每个工作线程的状态。是否有可能找到一个线程是否被阻塞在“pthread_cond_wait”?如果线程等待是pthread_cond_wait,那么STATE ==等待状态==正在运行。

while ((sharedvaluffer == 0) && (doneflag == 0)) { 
      pthread_cond_wait (&taks_added, &buffer); 
     }  

当然我们可以做到这一点,我们更多的代码。我们可以在上面的代码片段中添加一个全局变量, 将该线程标记为锁定。代码可以做

while ((sharedvaluffer == 0) && (doneflag == 0)) { 
       lock; 
       i_am_waiting = truel 
       unlock 
       pthread_cond_wait (&taks_added, &buffer); 
} 

问题是,如果有一个更容易的可扩展的方式。等待线程的堆栈是

Thread 6 (Thread 0x40800940 (LWP 20732)): 
#0 0x00002ba4567a9326 in [email protected]@GLIBC_2.3.2() 
#1 0x00000000007ce2ed in worker(void*)() 
#2 0x00002ba4567a5193 in start_thread() from /lib64/libpthread.so.0 
#3 0x00002ba458a82f0d in clone() from /lib64/libc.so.6 

回答

0

你可以使用将pthread_self()作为互斥所有权的标识返回。存储和比较。由于一个线程可以一次获取互斥锁,因此您将知道哪个线程正在运行(不等待),哪些不是。

+1

如果工作人员正在锁定某些互斥锁(即在共享互斥体的情况下),则不起作用 – cateof

+0

为什么不?每个线程都有自己的ID。保持一个可访问的'pthread_t current_owner'并在工作线程每次获得互斥量时更新它。您的信息线程然后将此变量与每个工作线程的ID进行比较。请记住,pthread_t在Linux上是int,但通常是其他系统中的结构,因此不能依赖原子性,需要额外的锁定。 – jweyrich

0

大概你正在使用的通知条件时,其被锁定的互斥体,如果是这样,您的信息线索,只需尝试锁定该互斥体 - 如果你得到它,那么它的可能在你采样的时候,线程正在等待,否则如果它阻塞,那么你知道线程正在做它的事情(即它已经获得了互斥体,这意味着它在它的关键部分)

+1

这会干扰线程。 – akappa

+0

尼姆的答案很好。反之。使用trylock进行互斥意味着一旦成功,另一个线程正在休眠。解决方案的问题在于互斥锁可能由两个工作线程共享 – cateof

+0

@akappa,为什么?这是一个trylock尝试,如果它失败了,那很好,线程正忙,如果成功了,你立即释放它,但你知道线程在那个时间点是睡眠。缺点是什么?在后一种情况下,你有另一个线程被迫等待的互斥体的额外锁定/解锁 - 除非这是一个实时关键应用程序,否则我不认为这是一个问题! – Nim

1

你可以在互斥寄存器的共享结构小号pthread_mutexattr_getpshared,其中每个线程具有pthread_self()借助于注册其状态(运行,不运行)。

在检查条件变量之前,可以设置s[pthread_self()]->state = WAITING,检查后可以设置s[pthread_self()]->state = WORKING

一定要设计结构,例如不会发生竞态条件。

1

我会去简单的路线,只是包括每个线程的状态枚举。在每个概念状态改变之前,你都会改变状态。

void worker(void* parm) 
{ 
    threadstate_t *state = (threadstate_t*)parm; 

    /* ... */ 
    while (...) { 
     state->current = STATE_WORKING; 

     /* ... */ 

     state->current = STATE_WAITING; 
     /* res = pthread_cond_wait(cond, mutex); */ 
    } 
} 

然后在您的interrogration螺纹:

void worker_dbg(void* parm) 
{ 
    threadstate_t *states = (threadstate_t*)parm; 
    int i; 

    while (run) { 
     for (i = 0; i < NWORKERS; ++i) { 
      /* _state is a map of states to strings */ 
      printf("Thread %d: %s\n", states[i].id, _state[states[i].current]); 
     } 
     sleep(30); 
    } 
} 

如果通过30秒是关闭因为国家得到了更新您打印后,它其实并不重要。无需锁定状态,因为您只能从拥有的工作人员处进行写入,并且只能从调试线程读取数据。

+1

主要原理与我的相似,但是您将状态附加到线程,而我在互斥体上执行该操作,所以您的方法比我的更清晰。 +1 – akappa

+0

你可以采取你的方法,并通过将每个互斥体添加到状态枚举中将它滚动到我的方法中。尽可能细化,因为你需要它。 – user7116

相关问题