"https://stackoverflow.com/questions/4424193/what happens to mutex when the thread which acquired it exits?noredirect=1&lq=1" 解釋當一個lock了mutex的線程退出了,卻沒 ...
解釋當一個lock了mutex的線程退出了,卻沒有主動unlock這個mutex時,會發生什麼
If you created a robust mutex by setting up the right attributes before calling pthread_mutex_init, the mutex will enter a special state when the thread that holds the lock terminates, and the next thread to attempt to acquire the mutex will obtain an error of EOWNERDEAD. It is then responsible for cleaning up whatever state the mutex protects and calling pthread_mutex_consistent to make the mutex usable again, or calling pthread_mutex_unlock (which will make the mutex permanently unusable; further attempts to use it will return ENOTRECOVERABLE).
假設在pthread_mutex_init的時候,通過設置合適的屬性得到一個robust mutex,當一個擁有該mutex的線程exit,並且沒有unlock這個mutex的時候,該mutex就會進入一個specail state。另外一個線程想要lock這個mutex的時候,會返回一個EOWNERDEAD錯誤。這個時候就需要清除該mutex的狀態,有兩個辦法:
- 調用pthread_mutex_consistent可以使得改mutex再次usable
- pthread_mutex_unlock使得該mutex永久unusable,嘗試再次使用該mutex的將會得到ENOTRECOVERABLE錯誤
For non-robust mutexes, the mutex is permanently unusable if the thread that locked it terminates without unlocking it. Per the standard (see the resolution to issue 755 on the Austin Group tracker), the mutex remains locked and its formal ownership continues to belong to the thread that exited, and any thread that attempts to lock it will deadlock. If another thread attempts to unlock it, that's normally undefined behavior, unless the mutex was created with the PTHREAD_MUTEX_ERRORCHECK attribute, in which case an error will be returned.
對non-robust mutexes,如果持有鎖的線程退出且沒有unlock該鎖,那麼該mutex將會永久不可以使用。這個mutex會保持被已經退出的該線程持有lock的狀態,任何嘗試lock這個mutex的線程將陷入deadlock狀態。如果任何線程嘗試unlock這個mutex,那麼將會產生undefined behavior。但如果mutex創建的時候設置了PTHREAD_MUTEX_ERRORCHECK屬性,那麼unlock將會返回錯誤。
On the other hand, many (most?) real-world implementations don't actually follow the requirements of the standard. An attempt to lock or unlock the mutex from another thread might spuriously succeed, since the thread id (used to track ownership) might have been reused and may now refer to a different thread (possibly the one making the new lock/unlock request). At least glibc's NPTL is known to exhibit this behavior.
但是,很多real-world的實現版本卻沒有滿足standard的要求。由於thread id可能會被重用,所以,有時候lock或者unlock會產生不合邏輯的成功,比如一個線程A lock了某個mutex,然後該A線程id給別的線程B用了,那麼線程B去unlock也會成功。比如glibc's NPTL就會表現出這樣的行為。