Win32程式設計: _beginthreadex or CreateThread?
先說結論,永遠先用_beginthreadex()來建立新的執行續,把它當作是你的 Code Convention。
為什麼?先從動機說起。 在 C Run-Time (CRT) 函式庫裡有許多函式在多執行續的環境下,會利用 Thread Local Storage (TLS) 去存取每個獨立執行續的資源,藉此達到 Thread-Safe。 舉例來說,errno 是檢查錯誤碼的變數,在多執行續的環境下,如果A()和B()兩個函式從不同的執行續改寫了 errno,那麼接下來的程式碼就無法確認 errno 來決定上面一個函式究竟是成功還是失敗。 為了解決這種問題,在多執行續的 CRT 下,errno 會被替換成 #define errno (*_errno())。_errno() 裡面做的事情就是去取出 TLS 裡面存放的 per-thread errno。這樣每一個執行續都有自己的 errno,不用擔心內容不正確的問題。 像是 errno 這樣的應用還有很多,它們都是存放在 _tiddata 這個結構中。_tiddata 又是放在 TLS 裡面。 再回來看_beginthreadex(),它比 CreateThread() 是多做了一些事情。最主要就是多初始一份 _tiddata 並且放在新的執行續的 TLS 中,讓 CRT 的函式可以使用這些 _tiddata 來達成 Thread-safe。 你可能會問,那...我的產品都已經釋出了,而且都是用CreateThread(),怎麼辦?先別擔心,先讓我們來看沒有正確使用 _beginthreadex() 會造成什麼影響。
如果是用 Multithread Dynamic-Link C Run-Time 看起來就沒什麼問題囉。(謎之聲:那個在 Production Code 用了 CreateThread 的人是誰呢? XD) |
|