2011-06-22 56 views
3

我們試圖將一些代碼從Solaris移植到HPUX。 Solaris使用它自己的線程API時,HPUX使用Pthread API。我們在遷移過程中遇到的一個問題是,強大的互斥體並未在HPUX上實施,因爲它不需要實施以保持POSIX兼容。從當前線程中查找活動線程的狀態。 (強大的互斥體的實現)

我們嘗試使用pthread_mutex_trylock使等待隊列中的線程不會阻塞。我們需要一些方法來確定互斥量的所有者線程是否活着。如何從調用線程獲取該線程的狀態?

感謝提前一噸, Aditya。

+0

+1有趣的問題。我認爲最好的答案是「你無法有效地解決問題」,但我試圖提供一些原因和潛在的(低效率)解決方法。 –

回答

2

不幸的是安東尼的方法有多種競爭條件:

  1. 有時間的線程獲取互斥和存儲本身作爲所有者之間的間隔。如果另一個線程在trylock失敗並想檢查所有者,它可能會發現所有者仍然不成文。在這種情況下,它可以等待,希望所有者能夠寫出自己的身份,但如果所有者在恰當的(錯誤的)時刻死亡,那麼等待就會陷入僵局。
  2. 無論擁有者標識符與互斥體存儲在一起,都可以在擁有者死亡後重新分配。請注意,只存儲一個線程ID將是無用的,因爲線程ID在進程間並不是唯一的,強健的互斥體語義只對進程共享的互斥體有意義。 (在單個進程中,您可以完全控制線程終止;它們無法終止不可預知的終止,所以您可以在線程退出時正確清理線程並釋放它們的互斥體。)如果您使用PID,唯一的情況是可以避免如果進程是您自己的子進程並且您還沒有等待,PID將被重新分配。

正確實施強大的互斥鎖確實需要內核的幫助以避免競爭條件。當然,您可以使用令人討厭的慢速技術,其中每個鎖定和解鎖操作都需要一個系統調用來模擬系統上強大的互斥鎖,而無需像futex那樣強大的互斥鎖支持。使用fcntl鎖定或SysV信號量,這兩者都具有可以實現自動和原子解鎖所有者註冊的語義...

1

一般來說,你不能說出哪個線程擁有互斥鎖,不必介意它是否存在。

如果你想知道這些信息,那麼你必須自己存儲---在鎖定互斥鎖之後立即存儲線程ID,然後在解鎖互斥鎖之前清除該值。這些商店不得不是原子的,或者被互斥體本身保護(顯然,如果你使用互斥體,那麼你不能檢查這個互斥體的問題,否則你會遇到遞歸問題)。然後,您可以使用此存儲的線程ID來檢查線程是否處於活動狀態。

這假定(a)你的線程不會在獲取互斥鎖和設置所有者之間死掉,並且(b)線程ID不會被重用。它也掩蓋了「檢查線程是否活着」的部分 - 這本身並不是微不足道的。

如果你假設某個線程可能在任何時候死亡,那麼在沒有OS支持的情況下構建「健壯的互斥體」是不可能的。

+0

但是然後保護線程ID的互斥量將需要自己的線程ID ...這是大象一路下來! – Nemo

+0

@Nemo:也有更深層次的問題。看到我的答案。 –