RedFox20 + Oktonion + WinBuild 的組合pthread-win32
分支
PThread https://github.com/WinBuilds/pthread-win32 更改:
這是 pthreads-win32 軟體包 2.10.0.0 版本的分支。該前叉的 ABI 與原來的不同。
所做的更改:
ptw32_handle_t
中的重用計數器類型已從int
更改為size_t
,以便於長時間運行的伺服器。
從pthread_once_t
中刪除了未使用的元素
該程式庫經常與我們的其他 Visual Studio 2022 專案一起測試。
一般來說,我在工作中使用(並且已經使用過)MSVC20xx 專案文件。 Makefiles 使用的頻率要低得多,而且可能已經過時。
請注意提交訊息 d4b0ef6b:雖然 MSVC2022/2019 專案已配置為適合我的內部設置,但它可能不適合您的。
當然,您始終可以手動編輯設置,但是當您需要對許多vcxproj
專案文件執行此操作時,編寫任務腳本可能是最佳選擇。請參閱update-vcxproj.js
和patch-vcxproj.js
以取得執行此類操作的範例腳本。我使用這些來確保我的所有C/C++ 專案都具有完全相同的建置設置,這樣我就不會遇到任何令人討厭的運行時意外,因為某些專案決定使用稍有不同的調試/發布靜態/DLL 運行時庫進行構建,等等:你可以獲得無數種方法?透過 Windows 環境中的建置系統。樂趣! ?
(2021-12-17)
這是一個微版本,主要包含管理修復。
mkdir b && cd b && cmake -G "Visual Studio 16 2019" ..
進行獨立測試:好的。這意味著幾個潛伏的錯誤已被修復,並且當 C 原始程式碼有條件編譯為 C++ 時,我們已經包含了 CMake 廢話的解決方法(我仍然不喜歡該工具)(另請參閱 pthread-EH.cpp和pthread-JMP.c:兩個新的包裝器原始檔)。 這是一個微版本,主要包含管理修復。
透過完成隨附的測試套件以及壓力和基準測試,MSVC 和 MinGW64 版本已在 SMP 架構(Intel x64 Hex Core)上進行了測試。
請務必針對測試套件執行您的建置。如果您發現失敗,請考慮您的工具鏈可能如何導致失敗。有關我們用來成功通過測試的工具鍊和測試系統的更多詳細說明,請參閱自述文件。
對於 64 位元和 32 位元 GNU CC 構建,我們建議使用 MinGW64 而不是 MinGW,只是因為 C++ 構建的 MinGW DWARF2 異常處理會導致線程取消的一些問題。
MinGW64 還包含自己的本機 pthreads 實現,您可能更喜歡使用它。如果您希望建立我們的庫,您需要在安裝時選擇 Win32 本機執行緒選項。我們也建議為 MinGW64-w32 建構選擇 SJLJ 異常處理方法。對於 MinGW64-w64 構建,SJLJ 或 SEH 異常處理方法應該有效。
(2018-08-08)
請注意,這是一個新的主要版本。主要版本增量引入了兩個 ABI 更改以及其他命名更改,這些更改將需要重新編譯鏈接應用程序,並且可能需要對配置和源文件中的編譯時宏引用進行一些文本更改,例如 PTW32_* 更改為 PTW32_ 、 ptw32_ 改為ptw32_* 等。
經所有重要相關貢獻者同意,pthreads-win32 / pthreads4w 版本 3(除四個文件外)將根據 Apache License v2.0 的條款發布。 APLv2 與 GPLv3 和 LGPLv3 授權相容,因此該程式碼可以繼續合法地包含在 GPLv3 和 LGPLv3 專案中。
重要相關貢獻者被定義為貢獻了實現未來版本中存在的功能的原始程式碼的人。這不包括一些貢獻者,他們貢獻了過時的程式碼,或提供了修復錯誤、出於美觀或實用目的重新組織程式碼或改進建置過程的補丁。這種區別是必要的,以便在可能無法聯繫到所有貢獻者的情況下繼續前進。所有貢獻者都列在 CONTRIBUTORS 文件中。
將保留 LGPL 但更改為 v3 的四個檔案是用於配置 GNU 環境建置的檔案:
aclocal.m4
configure.ac
GNUmakefile.in
tests/GNUmakefile.in
請求此更改或在諮詢後同意此更改的貢獻者是:
pthreads-win32 / pthreads4w 版本 2 版本將保留 LGPL,但版本 2.11 及更高版本將在該許可證的 v3 下發布,因此反向移植到 v2 的 pthreads4w 版本 3 代碼的任何添加都不會污染該代碼。
2011 年 2 月 26 日之後的一些變更可能與 Windows 2000 之前的系統不相容。
自 2.8.0 以來所有版本中的新錯誤修復尚未應用於 1.xx 系列。
透過完成隨附的測試套件以及壓力和基準測試,MSVC、MinGW 和 MinGW64 版本已在 SMP 架構(Intel x64 Hex Core)上進行了測試。
請務必針對測試套件執行您的建置。如果您發現失敗,請考慮您的工具鏈可能如何導致失敗。有關我們用來成功通過測試的工具鍊和測試系統的更多詳細說明,請參閱自述文件。
對於 64 位元和 32 位元 GNU CC 構建,我們建議使用 MinGW64 而不是 MinGW,只是因為 C++ 構建的 MinGW DWARF2 異常處理會導致線程取消的一些問題。
MinGW64 還包含自己的本機 pthreads 實現,您可能更喜歡使用它。如果您希望建立我們的庫,您需要在安裝時選擇 Win32 本機執行緒選項。我們也建議為 MinGW64-w32 建構選擇 SJLJ 異常處理方法。對於 MinGW64-w64 構建,SJLJ 或 SEH 異常處理方法應該有效。
除以下內容外,此版本的功能與 v2.11.0 等效。
此版本引入了對 pthread_t 和 pthread_once_t 的更改,這將影響與該程式庫連結的應用程式。
pthread_t:仍然是一個結構體,但將重複使用計數器從 32 位元擴展到 64 位元。在 64 位元機器上,物件的整體大小不會增加,我們只需充分利用 4 個位元組的填充,即可降低計數器在長時間運行的應用程式中從小到實際上為零的風險。 64 位元重用計數器將無風險運行時間從幾個月(假設平均線程生命週期為 1 毫秒)延長到幾個世紀(假設平均線程生命週期為 1 奈秒)。
pthread_once_t:刪除兩個長期廢棄的元素並減少其大小。
(2018-08-08)
自 2.8.0 以來所有版本中的新錯誤修復尚未應用於 1.xx 系列。
2011 年 2 月 26 日之後的一些變更可能與 Windows 2000 之前的系統不相容。
pthreads-win32 / pthreads4w 版本 2.11 和所有未來的 2.x 版本將根據 Lesser GNU 公共授權版本 3 (LGPLv3) 發布。
軟體的下一個主要版本(版本 3)將根據 Apache 授權版本 2.0 (ALv2) 發布。根據 LGPLv3 發布 2.11 將允許對該軟體版本 3 的修改向後移植到版本 2。除此之外,目前使用此程式庫的任何 GPL 專案將能夠繼續在其專案中使用此程式碼的版本 2 或 3。
欲了解更多信息,請參閱:https://www.apache.org/licenses/GPL-compatibility.html
為了與此變更保持一致,從此時起,僅根據 ALv2 條款針對此軟體的版本 3 接受對此函式庫的修改。然後,它們將在適當的情況下向後移植到版本 2。
我們希望在發布 2.11 版本的同時發布版本 3。
透過完成隨附的測試套件以及壓力和基準測試,該版本已在 SMP 架構(Intel x64 Hex Core)上進行了測試。
請務必針對測試套件執行您的建置。如果您發現失敗,請考慮您的工具鏈可能如何導致失敗。有關我們用來成功通過測試的工具鍊和測試系統的更多詳細說明,請參閱自述文件。對於 64 位元和 32 位元 GNU CC 構建,我們建議使用 MinGW64 而不是 MinGW32。 MinGW64 還包含自己的獨立 pthreads 實現,您可能更喜歡使用它。
對於 Microsoft 工具鏈建置: (1) 靜態連結要求此程式庫和任何連結程式庫或應用程式都使用 /MT 進行一致編譯。
(2) 靜態函式庫已重新命名為 libpthreadV*.lib,以區別於 DLL 導入函式庫 pthreadV*.lib。
(3) 如果您使用混合鏈接,例如將庫的靜態 /MT 版本鏈接到與 /MD 鏈接的應用程序,您可以使用 GetLastError() 來詢問錯誤代碼,因為庫設置了兩個 errno(通過 _set_errno ( )) 和SetLastError()。
刪除在標頭中設定 PTW32_USES_SEPARATE_CRT 的嘗試,這可能會導致意外結果。在某些情況下,使用者可能希望在建立庫或應用程式或兩者時在其環境中明確定義它以調用它的效果。請參閱自述文件。 ——羅斯·約翰遜
該庫在完全靜態連結的場景下應該更加可靠。注意:我們已刪除 PIMAGE_TLS_CALLBACK 程式碼並恢復為較早的方法,該方法在所有編譯器版本中似乎都更可靠。
對 GNUmakefile 的各種更正。儘管此文件已被刪除,但為了完整性,變更已記錄為對儲存庫的提交。
MinGW64-w64 將 pid_t 定義為 __int64。 sched.h 現在反映了這一點。
一些測試已被修復,這些測試在負載下的機器上會失敗。使用類似的原始機制來同步執行緒的其他測試(這些是單元測試)也應用了相同的改進:semaphore5.c 認識到 sem_destroy 可以合法地傳回 EBUSY; mutex6*.c、mutex7*.c 和 mutex8*.c 都用輪詢循環取代了單一 Sleep()。
(2016-09-18)
自 2.8.0 以來所有版本中的新錯誤修復尚未應用於 1.xx 系列。
2011 年 2 月 26 日之後的一些變更可能與 Windows 2000 之前的系統不相容。
透過完成隨附的測試套件以及壓力和基準測試,該版本已在 SMP 架構(Intel x64 Hex Core)上進行了測試。
請務必針對測試套件執行您的建置。如果您發現失敗,請考慮您的工具鏈可能如何導致失敗。有關我們用來成功通過測試的工具鍊和測試系統的更多詳細說明,請參閱自述文件。對於 64 位元和 32 位元 GNU CC 構建,我們建議使用 MinGW64 而不是 MinGW32。 MinGW64 還包含自己的獨立 pthreads 實現,您可能更喜歡使用它。
新例程: pthread_timedjoin_np() pthread_tryjoin_np()
sched_getaffinity() sched_setaffinity() pthread_getaffinity_np() pthread_setaffinity_np() pthread_attr_getaffinity_np() pthread_attr_setaffinity_np()
pthread_getname_np() pthread_setname_np() pthread_attr_getname_np() pthread_attr_setname_np()
pthread_win32_getabstime_np()
GNU 編譯器環境(MinGW32 和 MinGW64)現在可以選擇使用 autoconf 自動設定建置。
建置:新增了新的 makefile 目標,並修改或刪除了現有目標。例如,目標是建置和測試 dll 和靜態庫的所有可能配置。
GNU 編譯器建置現在明確使用 ISO C 和 C++ 2011 標準相容性。如果您的 GNU 編譯器不支援此功能,請考慮更新。現在可以透過「配置」腳本進行自動配置。該腳本必須使用 autoconf 產生 - 請參閱 README 檔案。感謝 MinGW 計畫的 Keith Marshall。
靜態連結:自動靜態功能已移至 dll.c 並進行了擴展,以便使用 MSVC8 及更高版本進行構建時不再需要應用程式調用 pthread_win32_thread_detach_np()。也就是說,所有 DllMain 功能現在都自動用於這些建置的靜態連結。
一些 nmake 靜態連結目標已停用:由於 TLS 行為問題,Makefile 中的 V*-small-static* nmake 目標已停用。這個問題是由 test/semaphore3.c 暴露的,其中線程內的 pthread_self() 呼叫無法返回正確的 POSIX 線程句柄,而是返回一個新的“隱式”POSIX 線程句柄。隱式 pthread 句柄具有分離執行緒狀態,這會導致執行緒內的 pthread_detach() 呼叫傳回 EINVAL。 V*-static* 目標似乎不受影響。主要區別在於後者是從單一編譯單元產生的。
小目標檔案靜態連結現在可以使用 (MinGW)。自動靜態程式碼是必需的,但沒有任何明確引用此程式碼,因此正在最佳化。
sem_getvalue() 可以傳回 errno 值,而不是設定 errno 並且傳回 -1。
如果庫與運行時庫靜態鏈接,則 Errno 值將會丟失,這也意味著應用程式使用單獨的運行時實例。情況仍然如此,只是添加了一個建置開關,允許合併更強大的錯誤狀態,即允許透過 GetLastError() 檢索返回程式碼。
確定了來自 Mingw32 的 GCE (GNU C++) 建置配置的取消和 pthread_exit() 重大失敗的原因。不確定這是否是普遍現象,還是僅在建置在 64 位元系統上運行的 32 位元庫和應用程式時出現。在 64 位元系統上執行的 Mingw64 32 位元建置(啟用 multilib 建置的 GCC)不會出現這些故障。
版本 2.9.x 中引入的 pthread_key_delete() 錯誤導致此例程以測試套件未偵測到的方式失敗。新增了一個新測試來確認此例程行為正確,特別是在執行緒退出之前刪除帶有析構函數的鍵時。
pthread_win32_process_attach_np() 修正了尋找和載入 QUSEREX.DLL 時潛在的故障/安全問題。
_POSIX_THREAD_ATTR_STACKADDR 現在在 pthread.h 中設定為等於 -1。因此,pthread_attr_setstackaddr() 現在傳回 ENOSYS。以前該值已儲存並且可以檢索,但在其他情況下未使用。 pthread_attr_getstackaddr() 會對應地傳回 ENOSYS。
修復了 pthread_mutex_init() 中潛在的記憶體洩漏。只有當互斥體初始化失敗時才會發生洩漏(如果有的話,則極為罕見)。
修復了導致庫忙等待的亞毫秒超時。
修復 MCS 鎖定中的競爭條件和崩潰。 ptw32_mcs_lock_acquire 中的等待佇列管理程式碼與 ptw32_mcs_lock_release 中的佇列管理程式碼競爭並導致分段錯誤。
(2012-05-27)
自 2.8.0 以來此版本中的新錯誤修復尚未應用於 1.xx 系列。
此版本取代了極其簡短的 2.9.0 版本,並添加了一些最後一刻的非程式碼更改,以便在 dll 中嵌入更好的描述性屬性,以指示目標體系結構和建置環境。
2011 年 2 月 26 日之後 CVS 中的某些變更可能與 Windows 2000 之前的系統不相容。
現在不鼓勵使用“C”版本以外的庫。也就是說,「C++」版本未通過某些測試且不提供任何附加功能。
此版本已通過完成隨附的測試套件、壓力和基準測試,在 SMP 架構(Intel x64 Hex Core)上進行了測試。
DLL 屬性現在正確包含目標體系結構,即在資源管理器中右鍵單擊檔案pthreadVC2.dll 並選擇“詳細資料”標籤將在描述欄位中顯示編譯器和體系結構,例如“MS C x64”或“ MS C x86」。
現在可以透過 config.h 中的#define RETAIN_WSALASTERROR
來決定對winsock 函式庫的依賴。預設情況下它是未定義的,除非定義了 WINCE(因為我(RJ)不確定那裡的依賴關係)。
(MSC 和 GNU 版本)靜態連結庫現在會在程式啟動/退出時自動初始化和清理,即靜態連結應用程式無需明確呼叫程式 pthread_win32_process_attach_np() 和 pthread_win32_process_detach_np()。如果我(RJ)正確瞭解了該進程,則在程式退出時也會呼叫每個執行緒例程 pthread_win32_thread_detach_np() 來清理主 Windows 本機執行緒所取得的 POSIX 資源。如果應用程式依賴回收的 POSIX 資源或執行 POSIX TSD (TLS) 析構函數,則呼叫 POSIX API 例程的其他 Windows 本機執行緒可能需要在執行緒退出時呼叫執行緒分離例程。有關這些例程的說明,請參閱 README.NONPORTABLE。
健全的互斥鎖是在 PROCESS_PRIVATE 範圍內實現的。請注意,pthread_mutex_* 函數可能會為穩健互斥體傳回與正常使用時不同的錯誤代碼,例如,當互斥體穩健時,需要pthread_mutex_unlock 來檢查所有互斥體類型的所有權,而對於「正常」非互斥體則不會發生這種情況。
pthread_getunique_np 的實作是為了與其他一些實作實作來源層級相容性。此例程傳回與執行緒唯一關聯的 64 位元序號。應用程式可以使用它來排序或散列 POSIX 線程句柄。
64 位元系統還有更多變化。
用於建置和測試 WinCE 的各種修改和修復。
修正 pthread_cond_destroy() - 不應該是取消點。修復了其他小建置問題。
從 pthread_cond_destroy() 中消除潛在的死鎖條件。
針對 Win64 建置和測試的各種修改。
對 QueueUserAPCEx 非同步取消幫助程式 DLL(這是單獨下載)和 pthreads 程式碼清理的各種修復。
刪除了潛在的 NULL 指標引用。
刪除了應用程式將呼叫 pthread_barrier_wait 的執行緒數限制為屏障計數的要求。也減少了barrier_wait和barrier_destroy之間的爭用。這項變更將稍微減緩屏障的速度,但將每個屏障消耗的信號量數量減半至一個。
修正了 sched_[gs]etscheduler 中的句柄洩漏。
從 pthread.h 中刪除了所有 POSIX 可重入函數相容性巨集。有些在語意上根本不正確。
線程不再嘗試將未捕獲的異常傳遞到線程範圍之外(僅限 C++ 和 SEH 建置)。未捕獲的異常現在會導致線程退出並返回代碼 PTHREAD_CANCELED。
許多特別針對 x64 的轉換修復、針對 x64 的互鎖修復和返工。
現在可以透過 config.h 中的#define RETAIN_WSALASTERROR
來決定對winsock 函式庫的依賴。預設情況下它是未定義的,除非定義了 WINCE(因為 RJ 不確定那裡的依賴關係)。
用於內部管理的幾個靜態 POSIX 互斥體被基於 MCS 佇列的鎖取代,以減少資源消耗,特別是 Win32 物件的使用。
為了安全起見,QuserEx.dll(如果使用)現在必須安裝在 Windows 系統資料夾中。
Robust[1-5].c - 穩健的互斥體sequence1.c - 每個執行緒唯一的序號
所有 mutex*.c 測試在適當的情況下都已進行修改,以便在相同條件下測試穩健的互斥體。在適當的地方向 benchtest*.c 添加了強大的互斥基準測試。
(2006-12-22)
自 2.7.0 以來此版本中的新錯誤修復尚未應用於版本 1.xx 系列。可能是時候放棄版本 1 了。
此版本尚未在 SMP 架構上進行測試。所有測試均在單處理器系統上通過。
即使沒有執行緒在等待信號量,Sem_destroy 也可能回傳 EBUSY。其他圍繞無效信號量結構(內部)的競爭也已被刪除。
semaphore5.c - 測試上述錯誤修復。
(2005-06-04)
此版本中的所有新功能均已向後移植到版本 1.11.0 中,包括在 pthread_once 中合併 MCS 鎖,但版本 1 和 2 仍然不相容,儘管它們現在在效能和功能上相同。
此版本已在單處理器和多處理器系統上進行了測試(通過了測試套件)。
Pthread_once 已被重新實現,以消除優先提升和其他複雜性,從而提高穩健性。非回收唯一的 Win32 句柄的競爭已被刪除。 pthread_once 的一般形式現在與 Alexander Terekhov 之前建議的相同,但不是“命名互斥體”,而是實現了基於隊列的鎖,它具有動態自初始化和銷毀所需的屬性。這個鎖也很有效率。 ABI 不受影響,因為 pthread_once_t 的大小沒有改變且 PTHREAD_ONCE_INIT 沒有改變,但是,窺視 pthread_once_t(應該是不透明的)內部的應用程式將會崩潰。
(2005-05-19)
此版本中的所有錯誤修復和新功能均已向後移植到版本 1.10.0 中。
此版本已在單處理器和多處理器系統上進行了測試(通過了測試套件)。感謝 TomoTherapy 的 Tim Theisen 詳盡地運行了 MP 測試,並在檢測到故障時提供了重要的觀察結果和數據。
(2005-05-09)
軟體包現在包含一個參考文件集,其中包含 HTML 格式的 Unix 風格手冊頁,這些手冊頁經過編輯以與 pthreads-win32 保持一致。該集也可以線上閱讀:http://sources.redhat.com/pthreads-win32/manual/index.html
再次感謝 Tim Theisen 在 MP 系統上執行預先發布的測試套件。
此版本中的所有錯誤修復和新功能均已向後移植到版本 1.9.0 中。
修改後的實作避免了對有問題的 HANDLE 的需要,並在鍵被刪除或線程退出(以先到者為準)後立即回收記憶體。
感謝 Aculab 的 Richard Hughes 識別並定位了洩漏點。
TSD 鍵析構函式現在最多可處理 PTHREAD_DESTRUCTOR_ITERATIONS 次,而不是只處理一次。 PTHREAD_DESTRUCTOR_ITERATIONS 已在 pthread.h 中定義了一段時間,但未使用。
修正 sem_post/sem_post_multiple 和 sem_wait 取消之間的信號量記帳競賽。這與上一個版本中修復的 sem_timedwait 問題相同。
sem_init、sem_post 和 sem_post_multiple 現在檢查信號量計數是否不會超過 _POSIX_SEM_VALUE_MAX。
雖然sigwait()只不過是一個空操作,但它至少應該是一個取消點,以符合標準。
stress1.c - 嘗試暴露條件變數和訊號量定時等待邏輯中的問題。此測試的靈感來自 Stephan Mueller 的範例測試程式碼,該程式碼用於識別上一個版本中的 sem_timedwait 錯誤。它不是常規測試套件的一部分,因為它可能需要一段時間才能運行。運行它:nmake clean VC-stress
tsd2.c - 如果在析構函數程式執行後 tsd 鍵值不為 NULL,則測試鍵析構函數是否重新執行。也測試 pthread_setspecic() 和 pthread_getspecic() 是否可以從析構函數呼叫。
(2005-04-26)
現在沒有計劃發布 3.0.0 版本來修復 pthread_once() 中的問題。 pthread_once 的其他可能實現仍將在未來可能的版本中進行研究,以嘗試降低目前實現的複雜性。
此版本中的所有錯誤修復和新功能均已向後移植到版本 1.8.0。
修復了 pthread_once 競爭(MP 系統上的失敗)。感謝 Tim Theisen 使用一系列編譯器在他的 MP 系統上執行詳盡的預發布測試: VC++ 6 VC++ 7.1 Intel C++ 版本 8.0 所有測試都通過。也進行了一些小的速度改進。
修正 pthread_mutex_timedlock() 中的整數溢位錯誤 - 在版本 2.2.0 中修復 sem_timedwait() 時遺失。當定義 NEED_SEM 時,此例程不再傳回 ENOTSUP - 它受支援(僅 3.0 之前的 WinCE 版本需要 NEED_SEM)。
修正 sem_timedwait() 中的逾時錯誤。
修正了 NEED_SEM 有條件包含的程式碼中的幾個問題。 NEED_SEM 包含的程式碼是為不實現 W32 信號量的系統提供的,例如 3.0 版本之前的 WinCE。當定義 NEED_SEM 時,使用這些系統的 W32 事件來建立 POSIX 訊號量的替代實作。程式碼在此版本中已完全重寫,以重複使用大多數預設 POSIX 信號量程式碼,特別是實作 pthreads-win32 支援的所有 sem_* 例程。 Tim Theisen 也在他的 MP 系統上透過 NEED_SEM 程式碼運行測試套件。所有測試都通過了。
現在,對於 Borland Builder 5.5 編譯器來說,該函式庫的建置不會出現錯誤。
pthread_once 太複雜了 - 但據測試可以確定它可以工作。
Borland 版本的 dll 由於記憶體讀取異常而未能通過某些測試。原因尚不清楚,但不排除編譯器錯誤。
(2005-04-12)
版本 1.7.0 是此版本中新功能和錯誤修復的向後移植。請參閱版本 2.0.0/General 下的早期註釋。
(2005-04-04)
新增了 makefile 目標來建立庫的靜態連結版本。 MinGW 和 MSVC 都有。請注意,這並不意味著 LGPL 許可發生任何變化,LGPL 許可仍然對分發與該庫靜態連結的軟體施加特定條件。
pthread_once() 中有一個已知錯誤。如果等待線程的優先權高於初始化線程,則取消 init_routine 會導致潛在的飢餓(即死鎖)問題。該問題將在該庫的 3.0.0 版本中修復。
修正 sem_timedwait() 中的整數溢位錯誤。凱文·盧西爾
修復靜態連結的預處理器指令。迪米塔·帕納約托夫
(2005-03-16)
(2005-03-16)
此版本代表 ABI 更改,DLL 版本命名已從 1 增加到 2,例如 pthreadVC2.dll。
版本 1.4.0 向後移植了此版本中包含的新功能。請將從該版本建置的 DLL 分發到基於 pthreads-win32 版本 1.xx 建置的應用程式的更新
包命名已更改,用版本號+描述資訊替換快照日期。例如,這個版本是「pthreads-win32-2-0-0-release」。
版本1.3.0
版本1.2.0
版本1.1.0
版本1.0.0
此快照主要修復了 snapshot-2004-11-03 中引入的 condvar bug。還包括 DLL 版本控制,以允許應用程式運行時檢查 Microsoft 相容的 DLL 版本信息,並擴展 DLL 命名系統以實現 ABI 和主要(非向後相容)API 更改。有關詳細信息,請參閱自述文件。
DLL 中新增了 Microsoft 風格的版本資源,供希望在執行時間檢查 DLL 相容性的應用程式使用。
pthreads-win32 DLL 命名已擴展,允許不相容的 DLL 版本在同一檔案系統中共存。有關詳細信息,請參閱README 文件,但簡要說明:雖然從現在開始,DLL 內的版本信息將隨著每個版本的發布而更改,但只有當新DLL 不向後兼容舊應用程序時,DLL 版本名稱才會更改。
版本控制方案借鑒了 GNU Libtool,DLL 命名方案則來自 Cygwin。如果遵守 Libtool 風格的編號規則,Cygwin DLL 命名方案會自動確保 DLL 名稱變更最小,且應用程式不會載入不相容的 pthreads-win32 DLL。
使用預先建置 DLL 的使用者會發現在此快照中 DLL/LIB 名稱有一個新的後綴 (1)。例如pthreadVC1.dll等。
某些 POSIX 巨集已變更。
這些變更旨在符合單一 Unix 規範版本 3,其中規定,如果設定為 0(零)或未定義,則應用程式可以使用 sysconf() 在執行時確定其值。 pthreads-win32 不實作 sysconf()。
以下巨集不再是未定義的,而是已定義的並設定為-1(未實現):
_POSIX_THREAD_ATTR_STACKADDR
_POSIX_THREAD_PRIO_INHERIT
_POSIX_THREAD_PRIO_PROTECT
_POSIX_THREAD_PROCESS_SHARED
定義了以下巨集並將其設為 200112L(已實現):
_POSIX_THREADS
_POSIX_THREAD_SAFE_FUNCTIONS
_POSIX_THREAD_ATTR_STACKSIZE
_POSIX_THREAD_PRIORITY_SCHEDULING
_POSIX_SEMAPHORES
_POSIX_READER_WRITER_LOCKS
_POSIX_SPIN_LOCKS
_POSIX_BARRIERS
定義以下巨集並將其設定為適當的值:
_POSIX_THREAD_THREADS_MAX
_POSIX_SEM_VALUE_MAX
_POSIX_SEM_NSEMS_MAX
PTHREAD_DESTRUCTOR_ITERATIONS
PTHREAD_KEYS_MAX
PTHREAD_STACK_MIN
PTHREAD_THREADS_MAX
由於對 pthread_t 進行了更改以提供唯一的 POSIX 線程 ID,因此在不重新編譯應用程式的情況下,從此快照生成的 DLL 無法與舊應用程式一起使用。
儘管此快照通過了擴展測試套件,但許多更改相當重大,並且某些應用程式可能會顯示與以前不同的行為,因此請謹慎採用。希望任何行為改變都是因為圖書館在工作上做得更好,而不是更糟。
pthread_create() 不再接受 NULL 作為執行緒參考參數。將導致段錯誤(記憶體存取錯誤),並且不會建立任何執行緒。
pthread_barrier_wait() 不再作為取消點。
修復 pthread_once() 中潛在的競爭條件
新增了相容性:PTHREAD_RECURSIVE_MUTEX_INITIALIZER、PTHREAD_ERRORCHECK_MUTEX_INITIALIZER、PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP、PTHREAD_ERRORCHECK_MUTUTEXINITIALIZER_NP
初步支援 Digital Mars 編譯器
更快的互斥體。這些已經按照 Alexander Terekhov 提供的模型進行了重寫,該模型減少了內核空間檢查,並消除了一些用於管理定時鎖到期和解鎖之間競爭的額外關鍵部分。請注意,新的互斥體不會強制執行嚴格的互斥體絕對 FIFO 調度,但是任何亂序鎖獲取都應該非常罕見。
更快的信號量。遵循與上述互斥體類似的模型,這些互斥體已被重寫以使用初步的使用者空間檢查。
sem_getvalue() 現在會傳回服務生的數量。
POSIX 執行緒 ID 現在具有更強的唯一性特徵。庫保證在至少 2^(wordsize) 個執行緒銷毀/創建週期內不重複使用相同的執行緒 ID。
semaphore4.c:測試新 sem_wait() 的取消。
semaphore4t.c:與 sem_timedwait() 類似。
rwlock8.c:測試和計時讀取/寫入鎖定的慢速執行路徑以及它們所基於的 CV、互斥體和信號量。
嘗試將 Watcom 新增至可以建置該程式庫的編譯器清單中。由於它是非線程感知的 errno,最終失敗了。庫建置但測試套件失敗。有關更多詳細信息,請參閱 README.Watcom。
注意:如果您不在應用程式中使用非同步取消,或者不需要取消被系統資源(例如網路 I/O)阻塞的線程,那麼預設的非搶佔式非同步取消可能就足夠了。但是,pthreads-win32 會在執行時間自動偵測這些元件的可用性,因此如果您以後改變主意,則無需從原始程式碼重建程式庫。
書籍和其他地方關於在任何應用程式中使用非同步取消的不可取性的所有建議仍然有效,但對於庫對 POSIX 標準的一致性而言,此功能是一個受歡迎的補充。
清理執行緒優先權管理。特別是,執行緒優先權的設定現在嘗試將 sched_get_priority_min/max() 傳回的範圍內的無效 Win32 值對應到有用值。請參閱「執行緒優先權」下的 README.NONPORTABLE。
pthread_getschedparam() 現在按照標準要求傳回由最近呼叫 pthread_setschedparam() 給出的優先權或由 pthread_create() 建立的優先權。以前,pthread_getschedparam() 錯誤地傳回了呼叫時正在運行的執行緒優先權,該優先權可能已被調整或暫時提升/降級。
sched_get_priority_min() 和 sched_get_priority_max() 現在在出錯時傳回 -1 並且設定 errno。以前,他們錯誤地直接回傳了錯誤值。
如果 DuplicateHandle 失敗,pthread_self() 將釋放新建立的隱式 POSIX 執行緒句柄,而不是回收它(不太可能)。
pthread_exit() 既不釋放也不回收隱式 POSIX 執行緒的 POSIX 執行緒結構。
自 John Bossom 最初實現以來,該函式庫允許非 POSIX 初始化執行緒(Win32 執行緒)呼叫 pthreads-win32 例程,從而與 POSIX 執行緒互動。這是透過為 Win32 執行緒創建一個動態 POSIX 執行緒 ID 來完成的,一旦創建,就允許完全相互互動。這並沒有擴展到線程取消(非同步或延遲)。現在確實如此。
如果前一個執行緒的 POSIX pthread_t 值已知,則任何執行緒都可以被任何其他執行緒(Win32 或 POSIX)取消。它的 TSD 析構函數和 POSIX 清理處理程序將在執行緒以 PTHREAD_CANCELED 退出程式碼(透過 GetExitCodeThread() 檢索)退出之前執行。
例如,這允許 Win32 執行緒以 POSIX 執行緒將/應該的相同方式呼叫 POSIX CV 例程,並使用 pthread_cond_wait() 可取消性和清理處理程序(pthread_cond_wait() 是 POSIX 取消點)。
透過新增取消,Win32 執行緒現在應該能夠呼叫所有有意義的POSIX 執行緒例程,包括信號量、互斥鎖、條件變數、讀取/寫入鎖、屏障、自旋鎖、tsd、清理推送/彈出、取消、 pthread_exit、調度等。
請注意,這些動態「隱式」POSIX 執行緒 ID 被初始化為具有延遲取消類型的分離(不可連線)。 POSIX 執行緒 ID 將由任何需要 POSIX 句柄的 POSIX 例程自動建立(當然,除非例程需要 pthread_t 作為參數)。 Win32 執行緒可以透過呼叫 pthread_self() 來發現它自己的 POSIX 執行緒 ID,如果需要,它將建立句柄並傳回 pthread_t 值。
測試上述新功能。
此快照修復了新測試案例來源的一些意外損壞。庫原始碼沒有更改。
進行了各種變更以加強 arg 檢查,並與更高版本的 MinGW32 和 MsysDTK 配合使用。
pthread_getschedparam() 等,修復了危險的執行緒有效性檢查。
sem_timedwait() 現在對不合理的絕對時間值使用更嚴格的檢查 - 這將導致意外的超時值。
ptw32_cond_wait_cleanup() 不再神秘地消耗 CV 訊號,但可能會產生更多虛假喚醒。據信 sem_timedwait() 呼叫正在消耗不應消耗的 CV 訊號。
修正了隱式線程 ptw32_threadDestroy() 中的記憶體洩漏。
修復了 pthread_cond_destroy() 中潛在的死鎖。當一個執行緒嘗試銷毀條件變數而另一個執行緒嘗試動態初始化它時,靜態宣告的 CV (PTHREAD_COND_INITIALIZER) 可能會發生死鎖。
先前,如果未定義,清理樣式將由編譯器/語言自動決定,並相應地定義以下其中一項:
PTW32_CLEANUP_SEH MSVC only
PTW32_CLEANUP_CXX C++, including MSVC++, GNU G++
PTW32_CLEANUP_C C, including GNU GCC, not MSVC
這些定義決定了清理的風格(請參閱 pthread.h),最重要的是,決定了執行取消和執行緒退出(透過 pthread_exit)的方式(請參閱 private.c 中的例程 ptw32_throw())。
簡而言之,當執行緒被取消或退出(透過pthread_exit())時,該程式庫的異常版本會拋出異常,該異常由執行緒啟動例程中的處理程序捕獲,以便無論在何處,都會發生正確的堆疊展開。
在此快照和未來快照中,除非建立明確定義(例如透過編譯器選項)PTW32_CLEANUP_SEH、PTW32_CLEANUP_CXX 或 PTW32_CLEANUP_C,否則建置現在始終預設為 PTW32_CLEANUP_C 樣式清理。此樣式在取消和 pthread_exit 實作中使用 setjmp/longjmp,因此即使連結到具有它的應用程式(例如 C++ 應用程式),也不會執行堆疊展開。這是為了與大多數當前商業 Unix POSIX 執行緒實作保持一致。 Compaq 的 TRU64 可能是例外(無雙關語),並且可能是未來的趨勢。
儘管之前沒有明確記錄,但仍然需要使用與連結的庫版本相同的 PTW32_CLEANUP_* 定義來建立應用程序,以便包含 pthread.h 的正確部分。也就是說,可能的定義需要以下函式庫版本:
PTW32_CLEANUP_SEH pthreadVSE.dll
PTW32_CLEANUP_CXX pthreadVCE.dll or pthreadGCE.dll
PTW32_CLEANUP_C pthreadVC.dll or pthreadGC.dll
例如,無論您的應用程式是C還是C++,如果您連結到pthreadVC.lib或libpthreadGC.a,那麼您必須定義PTW32_CLEANUP_C。
所有這一切的要點是:如果您沒有明確定義其中之一,則將使用本節頂部描述的預設值。
正如上面所解釋的,現在情況發生了變化,但為了讓這一點更清楚,這裡有一個例子:
如果您使用 MSVC++ 建立應用程序,即使用 C++ 異常,且未明確定義 PTW32_CLEANUP_* 之一,則 PTW32_CLEANUP_C++ 會在 pthread.h 中自動為您定義。您應該連結到 pthreadVCE.dll,它會展開堆疊。
如果您現在像以前一樣建立應用程序,pthread.h 現在將自動將 PTW32_CLEANUP_C 設為預設樣式,並且您將需要與 pthreadVC.dll 連結。當執行緒被取消或執行緒呼叫 pthread_exit() 時,現在不會發生堆疊展開。
您的應用程式現在很可能會以不明顯的方式表現出與先前版本不同的行為。最有可能的是,在取消執行緒後,本地實例化的物件可能不會被銷毀或清理。
如果您想要與以前相同的行為,那麼您現在必須使用編譯器選項明確定義 PTW32_CLEANUP_C++,並像以前一樣連結到 pthreadVCE.dll。
為什麼我們要讓預設樣式對異常不那麼友善?因為沒有商業 Unix POSIX 執行緒實作允許您選擇堆疊展開。因此,在 pthread-win32 中將其作為預設值提供是危險的。我們仍然提供選擇,但除非您有意識地選擇這樣做,否則您的 pthreads 應用程式現在將以類似的方式運行或崩潰,無論您使用什麼線程平台。或者至少這是希望。
為什麼不完全刪除庫的例外版本?有以下幾個原因:
為了能夠為與庫靜態連結的應用程式產生較小的圖像大小,大多數例程已被分成單獨的原始程式碼檔案。
這樣做是為了向後相容。舊的原始檔案被重複使用以將各個例程檔案聚合成更大的翻譯單元(透過一堆#include),以便編譯器仍然可以盡可能地進行最佳化,例如透過內聯,這只能在同一翻譯單元內完成。
也可以透過編譯名為「pthread.c」的單一檔案來建立整個函式庫,該檔案僅 #include 所有輔助聚合原始檔。編譯器可以使用它來執行更多例程內聯。
儘管 GNU 編譯器能夠產生具有必要分離的函式庫(-ffunction-segments 開關),但 AFAIK、MSVC 和其他編譯器沒有此功能。
最後,由於我使用 makefile 和命令列編譯,我不知道這種重組可能會對 IDE 專案檔案使用者造成什麼嚴重破壞。您應該能夠繼續使用現有的專案文件而不進行修改。
pthread_num_processors_np():
返回系統中可供進程使用的處理器數量,由處理器關聯遮罩決定。
pthread_timechange_handler_np():
提高對操作員或時間服務發起的系統時鐘變更的容忍度。
當應用程式從系統接收到 WM_TIMECHANGE 訊息時,可以呼叫此例程。目前,它會廣播所有條件變量,以便等待線程可以喚醒並重新評估其條件,並在需要時重新啟動定時等待。
由於 Win95 不提供此例程,因此該程式庫現在包含它自己的 InterlockedCompareExchange() 例程,只要 Windows 不提供它,就會使用該例程。 InterlockedCompareExchange() 用於實現自旋鎖和屏障,也用於互斥鎖。此例程依賴 i386 CPU 上不可用的 CMPXCHG 機器指令。因此,i386 處理器平台不再支援該程式庫(從快照 20010712 開始)。
僅用於原始碼可移植性 - rwlock 尚不能被進程共用。
pthread_rwlockattr_init()
pthread_rwlockattr_destroy()
pthread_rwlockattr_setpshared()
pthread_rwlockattr_getpshared()
如新的 POSIX 標準和 Single Unix Spec 第 3 版所定義的:
sem_timedwait()
pthread_mutex_timedlock() - Alexander Terekhov and Thomas Pfaff
pthread_rwlock_timedrdlock() - adapted from pthread_rwlock_rdlock()
pthread_rwlock_timedwrlock() - adapted from pthread_rwlock_wrlock()
[G++ 還沒有]
這樣做是為了防止衝突。
HANDLE、DWORD 和 NULL 會在 pthread.h 中暫時定義(如果尚未定義)。
不僅可以避免使用 pthread.def 文件,還可以提高效能。顯然,使用 dllimport 聲明函數會產生對該函數的直接調用,並避免了存根函數調用的開銷。
透過將定義pthread_cleanup_push/pop 的當前C++ 和SEH 版本的巨集替換為C 版本,可以使這對應用程式透明,但據我所知,當發生異常時,清理處理程序將無法按正確的順序與析構函數和異常清理處理程序一起運行。
一旦在線程中啟動取消,現在就不能無意中雙重取消。也就是說,一旦執行緒開始取消運行,取消操作就會被停用,後續的取消請求將回傳錯誤 (ESRCH)。
errno:不正確的編譯器指令導致使用本機版本的 errno 而不是 Win32 errno。兩個實例都是線程安全的,但應用程式在 pthreads-win32 呼叫後檢查 errno 將會是錯誤的。修復此問題還修復了測試套件中的錯誤編譯器選項(/MT 應該是 /MD),需要該選項來連結正確的庫 MSVCRT.LIB。
待補充
待補充
新的:
Renamed DLL and LIB files:
pthreadVSE.dll (MS VC++/Structured EH)
pthreadVSE.lib
pthreadVCE.dll (MS VC++/C++ EH)
pthreadVCE.lib
pthreadGCE.dll (GNU G++/C++ EH)
libpthreadw32.a
Both your application and the pthread dll should use the
same exception handling scheme.
已修復的錯誤:
MSVC++ C++ exception handling.
新增了一些新的測試。
新的:
asynchronous cancellation on X86 (Jason Nye)
Makefile compatible with MS nmake to replace
buildlib.bat
GNUmakefile for Mingw32
tests/Makefile for MS nmake replaces runall.bat
tests/GNUmakefile for Mingw32
已修復的錯誤:
kernel32 load/free problem
attempt to hide internel exceptions from application
exception handlers (__try/__except and try/catch blocks)
Win32 thread handle leakage bug
(David Baggett/Paul Redondo/Eyal Lebedinsky)
新增了一些新的測試。
已修復的錯誤:
ctime_r macro had an incorrect argument (Erik Hensema),
threads were not being created
PTHREAD_CANCEL_DEFERRED. This should have
had little effect as deferred is the only
supported type. (Ross Johnson).
添加了一些相容性改進,例如。
pthread_setcancelstate accepts NULL pointer
for the previous value argument. Ditto for
pthread_setcanceltype. This is compatible
with Solaris but should not affect
standard applications (Erik Hensema)
新增了一些新的測試。
錯誤修復 - 取消等待條件變數的線程現在可以正常工作(Lorin Hochstein 和 Peter Slacik)
修正了呼叫 pthread_exit() 時的異常堆疊清理問題
修正了條件變數中的錯誤 - (Peter Slacik): - 額外的爭用檢查 - 在定時 condvar 逾時後正確調整等待線程的數量。
一些小錯誤已修復。有關詳細信息,請參閱更改日誌檔案。
現在包含了更多 POSIX 1b 函數,但在呼叫時僅傳回錯誤 (ENOSYS)。他們是:
sem_open
sem_close
sem_unlink
sem_getvalue
一些內部支援的 POSIX 1b 函數現在可以作為導出函數使用:
sem_init
sem_destroy
sem_wait
sem_trywait
sem_post
sched_yield
sched_get_priority_min
sched_get_priority_max
一些小錯誤已修復。有關詳細信息,請參閱更改日誌檔案。
初次發布。