回答
信號量可能適合進程之間的信號傳遞。 對於多線程編程,應該避免使用信號量。如果您需要獨佔訪問資源,請使用互斥鎖。如果您需要等待信號,請使用條件變量。
即使是最經常提到的資源池的情況,與條件變量相比,使用條件變量可以更簡單,更安全。我們來看看這種情況。一個天真的實現與信號會是什麼樣子(僞):
wait for semaphore to open
take a resource out of the pool
use the resource
put it back to the pool
open the semaphore for one more thread
的第一個問題是信號不保護池從多個線程訪問。所以,需要另一種保護。讓它成爲一個鎖:
wait for semaphore to open
acquire the lock for the pool
take a resource out of the pool
release the lock
use the resource
acquire the lock
put the resource back to the pool
release the lock
open the semaphore for one more thread
需要採取額外的措施,以確保池訪問時不是空的。從技術上講,可以繞過信號量來訪問池,但它會破壞上述獲取過程的資源可用性保證。所以池應該只能通過該過程訪問。
到目前爲止好,但如果一個線程不想被動等待資源呢?是否支持無阻塞資源獲取?如果信號量本身支持非阻塞採集,這很容易;否則(例如在Windows上),這將是有問題的。信號量不能被繞過,因爲它會打破阻塞情況。只有在池不空的情況下才能通過信號量,如果在鎖下完成,可能會導致死鎖,但一旦釋放鎖,檢查空閒的結果將變得毫無用處。這可能是可行的(我沒有嘗試),但肯定會導致顯着的額外複雜性。
使用條件變量,可以很容易地解決這個問題。下面是阻止收購的僞代碼:
acquire the lock
while the resource pool is empty,
wait for condition variable to be signaled
take a resource out of the pool
release the lock
use the resource
acquire the lock
put the resource back to the pool
release the lock
signal the condition variable
在這種情況下是沒有問題的補充無阻塞收購:
acquire the lock
if the resource pool is not empty,
take a resource out of the pool
release the lock
if the pool was empty, return
正如你可以看到,它甚至不需要訪問條件變量,並且不會對阻塞情況造成傷害。對我來說,它明顯優於使用信號量。
連接池。
I.e.你有20個連接和150個線程。在這種情況下,您將擁有一個信號量來控制對20個連接的訪問。
+1:一個很好的簡單例子,但我想知道是否還有其他情況下信號量對於... – 2011-04-08 20:25:29
信號量可以通過一個線程獲取並在另一個線程中釋放。鎖通常不能這樣做。當線程A完成使用資源並將資源的控制權傳遞給線程B時,我已經使用了這個。我必須控制順序以避免在這種特定情況下發生死鎖。
- 1. 什麼時候應該使用AWS,什麼時候不使用
- 2. 什麼時候應該使用sed,什麼時候應該使用awk
- 3. 什麼時候應該使用memcpy,什麼時候應該使用memmove?
- 4. 什麼時候應該使用Import-Package,什麼時候應該使用Require-Bundle?
- 5. 什麼時候應該使用async/await,什麼時候不用?
- 6. 什麼時候使用信號和插槽,什麼時候不使用
- 7. 什麼時候應該使用datagrid,何時應該使用datagridview?
- 8. 什麼時候應該使用$(object),何時應該使用$ object?
- 9. 什麼時候應該使用FSharpFunc.Adapt?
- 10. 什麼時候應該使用_aligned_malloc()?
- 11. 什麼時候應該使用`use`?
- 12. 什麼時候應該使用$ rootScope?
- 13. 什麼時候應該使用$(document).ready?
- 14. 什麼時候應該使用html5 sessionStorage?
- 15. 什麼時候應該使用OWIN Katana?
- 16. 什麼時候應該使用流?
- 17. 什麼時候應該使用Promises?
- 18. 什麼時候應該使用setScriptTimeout?
- 19. 什麼時候應該使用助手?
- 20. 什麼時候應該使用Datomic?
- 21. 我什麼時候應該使用javax.swing.SwingUtilities.invokeLater()?
- 22. 什麼時候應該使用XS?
- 23. 什麼時候應該使用const?
- 24. 什麼時候應該使用退貨?
- 25. 什麼時候應該使用getElementById?
- 26. 什麼時候應該使用Solandra
- 27. 我什麼時候應該使用UITableViewCellSeparatorStyleSingleLineEtched?
- 28. 什麼時候應該使用@android:id /?
- 29. 什麼時候應該使用geom_map?
- 30. 什麼時候應該使用scala.util.DynamicVariable?
相關:http://stackoverflow.com/questions/2350544/in-what-situation-do-you-use-a-semaphore-over-a-mutex-in-c – 2011-04-08 20:20:02
舉一個例子:http://堆棧溢出。/ 2375132/releasesemaphore-does-not-release-the-semaphore/2375370#2375370 – 2011-04-08 20:49:24