靈活運用Unix 線程知識
今天我們來學習用Unix 線程的知識來解決問題。在 UNIX 編程中,我們會經(jīng)常使用系統(tǒng)調(diào)用來完成期望的功能;而與此同時,我們也需要付出大段的代碼來檢測、輸出錯誤和其他意外情況。
Unix 線程安全是為了避免數(shù)據(jù)競爭或者數(shù)據(jù)設置的正確性依賴于多個Unix 線程修改數(shù)據(jù)的順序。假設你的代碼所在的進程中有多個Unix 線程在同時運行,而這些線程可能會同時運行這段代碼。如果每次運行結果和單線程運行的結果是一樣的,而且其他的變量的值也和預期的是一樣的,就是Unix 線程安全的。
Unix 線程的使用中以下是系統(tǒng)調(diào)用失敗的可能原因:
系統(tǒng)可能出現(xiàn)資源短缺或者程序使用的資源可能超過系統(tǒng)為單個程序規(guī)定的上限。常見的情況有:程序可能嘗試分配大量內(nèi)存,或者同時打開很多文件等。
程序執(zhí)行操作時,可能會由于權限不足而被系統(tǒng)阻止。例如,程序可能會試圖寫一個只讀的文件,或者企圖訪問其他進程的內(nèi)存空間。 傳入系統(tǒng)調(diào)用的參數(shù)可能無效,原因可能是用戶提供無效輸入或者程序本身的 bug。例如,程序可能會傳入一個無效的內(nèi)存地址或者無效的文件描述符。
系統(tǒng)調(diào)用還有可能因為程序之外的原因出錯。系統(tǒng)調(diào)用訪問硬件的時候經(jīng)常會有這種情況發(fā)生。設備可能會出現(xiàn)異常錯誤或者不支持特定的操作,或者可能會出現(xiàn)磁盤沒有插入驅(qū)動器中的情況出現(xiàn)。 系統(tǒng)調(diào)用有的時候會被外部事件 ( 如信號等 ) 中斷。這可能不代表真正的調(diào)用失敗,但是如果有必要,程序應當重新嘗試執(zhí)行系統(tǒng)調(diào)用。
對于函數(shù)來說,在多Unix 線程或有異??刂屏鞯那闆r下 , 當某個函數(shù)運行到中途時 , 控制流 ( 也就是當前指令序列 ) 就有可能被打斷而去執(zhí)行另一個函數(shù)。而這個函數(shù)很有可能是它本身。如果在這種情況下不會出現(xiàn)問題 , 比如說數(shù)據(jù)或狀態(tài)不會被破壞,行為確定。那么這個函數(shù)就被稱做 " 可重入 " 的。
在多Unix 線程編程中,有兩種方法使庫函數(shù)可以保證其安全。一個是簡單的將合適的代碼使用互斥鎖包起來,這樣可以保證同時只有一個線程執(zhí)行這一段例程。雖然這種方法大部分情況下都能奏效,但是它的性能卻非常糟糕。而且對于諸如 strtok 函數(shù),該方法就完全不能工作了,因此很多 UNIX 系統(tǒng)都存在 _r 的接口函數(shù)。
另一個更好的辦法是確保庫函數(shù)可以同時在多個Unix 線程情況下安全的執(zhí)行。這里指的不僅僅是帶有后綴 _r 的可重入對等函數(shù);畢竟可重入和線程安全(Thread-Safe)是兩個不同的概念:可重入函數(shù)一定是Unix 線程安全的;線程安全的函數(shù)可能是重入的,也可能是不重入的;Unix 線程不安全的函數(shù)一定是不可重入的。所以諸如 malloc,free 等函數(shù)也在此列,屬于Unix 線程安全的庫函數(shù)。
當然,如果你在單線程應用程序中使用Unix 線程安全函數(shù)會在一定程度上降低性能,所以盡量避免在單線程應用程序中使用它們。
【編輯推薦】















 
 
 

 
 
 
 