2011-11-30 60 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

相關問題