2010-12-02 59 views
4

我目前正在構建一個用於內部使用的pthreads的瘦C++包裝。 Windows和QNX都是針對性的,幸運的是pthreads-win32端口似乎工作得很好,而QNX則符合POSIX的實際用途。pthread-win32擴展sem_post_multiple

現在,雖然實現信號燈,我打的功能

sem_post_multiple(sem_t*, int) 

這顯然是隻在並行線程-win32的可以選擇,但是從QNX丟失。顧名思義,該函數應該通過作爲第二個參數給出的計數來增加信號量。據我所知,該函數不是POSIX 1b和POSIX 1c的一部分。

雖然目前沒有對上述功能的要求,但我還是想知道爲什麼pthreads-win32提供了這個功能,以及它是否有用。我可以嘗試使用類似下面的模仿它QNX:

sem_post_multiple_qnx(sem_t* sem, int count) 
{ 
    for(;count > 0; --count) 
    { 
     sem_post(sem); 
    } 
} 

我問什麼是如何進行的建議/意見。如果一致意見建議爲QNX實現該功能,那麼我還會對建議的代碼剪切是否是可行的解決方案表示讚賞。

在此先感謝。 PS:爲了清楚起見,我刻意忽略了我的花哨的C++類。對於所有建議提振救援的人士:由於管理方面的原因,這不是我目前項目的一個選擇。

+1

這就是「管理」涉及技術決策時發生的事情...... :)如果你不需要它,你爲什麼要浪費時間來包裝它?對我來說,這個決定是明確的,跳過它...... – Nim 2010-12-02 22:00:36

+0

的確,除非你確定你需要它,否則我會完全跳過包裝POSIX信號量。信號量是90年代(甚至更早?)同步的成語。 POSIX互斥鎖,條件變量,rwlocks和螺旋鎖在實踐中更加有用。 – 2010-12-02 23:54:53

回答

1

在任何情況下,信號量都是POSIX中的可選擴展。例如,OS X似乎沒有完全實現它們。因此,如果您關心可移植性,無論如何,您都必須提供所需功能的包裝。

通過迭代sem_post模擬原子增量的方法肯定有缺點。

  • 它可能會差強人意, 其中通常sem_t在 性能是至關重要的情況下使用。
  • 此操作不會是 原子。因此,在完成循環之前,可能會發生令人困惑的事情 。

我會堅持只是必要的,嚴格POSIX符合。請注意0​​是信號量選項的另一個可選部分。

+0

提及`sem_timedwait()`+1我錯過了一個擴展,因爲它在QNX中提供 – Arne 2010-12-02 22:15:56

0

sem_post_multiple()是由win32-pthreads維護人員引入的非標準輔助函數。你的實現與他們的實現不一樣,因爲多個遞減不是原子的。這是否是一個問題取決於預期用途。 (就個人而言,我不會嘗試,除非/直到需要時實現此功能)。

+0

我在此期間實現了他們的實現,實際上他們的代碼與天真循環完全不同。 – Arne 2010-12-02 22:08:45

1

你的建議實施的sem_post_multiple不能很好地與sem_getvalue玩,因爲sem_post_multiple是一個原子增加,因此這是不可能的「同時」呼叫sem_getvalue返回任何中間值。

就我個人而言,我想把它們都拋在一邊:試圖將基本的同步操作添加到缺少它們的系統是一個杯子的遊戲,並且您的包裝可能很快就會停止「瘦」。所以,除非你有使用sem_post_multiple的代碼,否則不要進入它,你必須移植。

0

這是一個有趣的問題。 +1。

我同意目前流行的共識,認爲實施該功能可能不是一個好主意。儘管在大多數情況下,您提議的實現可能會工作得很好,但肯定會由於非原子性而導致結果顯着不同。下面是一個(非常)做作情況:

  • 開始線程A這就要求sem_post_multiple(S,10)
  • 等待S上線程B被釋放。線程B殺死線程A.

在上述不友好的場景中,原子版本會將信號量增加10個。對於非原子版本,它只能增加一次。這個例子在現實世界當然不太可能。例如,殺死一個線程幾乎總是一個壞主意,更不用說它可能會將信號量對象置於無效狀態。 Win32實現可能會在信號量上留下互斥鎖 - see this for why