Windows C 多線程編程的庫支持

Windows C 多線程編程的庫支持

線程實質上是程序中的執行路徑。也是 Win32 安排的最小執行單元。線程包括堆棧、CPU 寄存器的狀態和系統計劃程序執行列表中的項。每個線程共享所有進程的資源。

進程包括一個或多個線程和代碼、數據和內存中的其他程序資源。典型的程序資源是打開的文件、信號燈和動態分配的內存。當系統計劃程序給予其中的一個線程執行控制時,即執行程序。計劃程序確定應當運行哪些線程以及它們應當何時運行。較低優先級的線程可能必須等到較高優先級的線程完成任務後才能運行。在多處理器計算機上,計劃程序可以將單個線程移到不同的處理器以平衡”CPU 負荷。

進程中的每個線程都獨立運行。除非使這些線程相互可見,否則線程分別執行,對進程中的其他線程一無所知。線程共享公共資源,但是,必須使用信號燈或其他進程間的通信方法協調它們的工作。

1、多線程編程的庫支持

如果在執行 printf 函數時有線程被 Win32 計劃程序掛起,則程序的其他線程中的某一個可能會開始執行。如果第二個線程也調用 printf,數據可能會損壞。爲避免這種情況,必須限制對函數使用的靜態數據的訪問,一次只允許一個線程訪問數據。

因爲每個線程具有不同的堆棧,所以不需要序列化對基於堆棧的(自動)變量的訪問。因此,只使用自動(堆棧)變量的函數是可重入的。標準 C 運行時庫(如 LIBC)的可重入函數的數量有限。對於需要使用通常不可重入的 C 運行時庫函數的多線程程序,應該使用多線程庫 LIBCMT.LIB 來生成。

多線程 C 庫:LIBCMT.LIB MSVCRT.LIB

支持庫 LIBCMT.LIB 是可重入庫,用於創建多線程程序。調用共享的 MSVCRT70.DLL 中代碼的 MSVCRT.LIB 庫也是可重入庫。當應用程序調用這些庫中的函數時,可以應用下列規則:

所有庫調用必須使用 C (__cdecl) 調用約定;使用其他調用約定(如 __fastcall __stdcall)編譯的程序必須使用它們調用的運行時庫函數的標準包含文件。

傳遞到庫函數的變量必須由值傳遞或轉換爲指針。

使用 LIBCMT.LIB 生成的程序不與它們所調用的任何動態鏈接庫共享 C 運行時庫代碼或數據。

LIBCMT.LIB MSVCRT.LIB 以外的其他選擇

如果不使用 LIBCMT.LIB 來生成多線程程序,必須執行下列操作:

使用標準 C 庫並且只允許可重入函數集進行庫調用。

使用 Win32 API 線程管理函數,如 CreateThread

通過使用 Win32 服務(如信號燈和 EnterCriticalSection LeaveCriticalSection 函數),爲不可重入的函數提供自己的同步。

警告   多線程庫 LIBCMT.LIB 包括 _beginthread _endthread 函數。_beginthread 函數執行初始化,若沒有該函數,許多 C 運行時函數將失敗。如果要調用 C 運行時函數,必須使用 C 程序中用 LIBCMT.LIB 生成的 _beginthread,而不是 CreateThread

多線程庫編譯選項

若要生成使用 C 運行時庫的多線程應用程序,必須通知編譯器使用特殊版本的庫 (LIBCMT.LIB)。若要選擇這些庫,請首先打開項目的屬性頁對話框(視圖菜單)並單擊 C/C++ 文件夾。選擇代碼生成頁。從運行時庫下拉框中選擇多線程。單擊確定按鈕以返回編輯狀態。

命令行中的多線程庫編譯器選項 (/MT) 是用 LIBCMT.LIB 生成多線程程序的最佳途徑。在創建新項目的過程中指定多線程應用程序時,自動設置此選項,此選項將 LIBCMT 庫名嵌入對象文件中。

2、多線程編程的包含文件

Microsoft Visual C++ 的包含文件包含使用 LIBCMT.LIB 的多線程應用程序的條件部分。若要使用適當的定義編譯應用程序,可以:

使用上一節中所述的多線程庫編譯器選項進行編譯。

在源文件中或在命令行上使用 /D 選項定義符號常數 _MT

在庫中實現 C 運行時庫函數時,標準包含文件聲明它們。如果使用完全優化 (/Ox) fastcall 調用約定 (/Gr) 選項,編譯器假設應使用寄存器調用約定調用所有函數。運行時庫函數是使用 C 調用約定編譯的,標準包含文件中的聲明通知編譯器生成對這些函數的正確外部引用。

3、線程控制的 C 運行時庫函數

所有 Win32 程序都至少有一個線程。任何線程都可以創建附加線程。線程可以快速完成其工作,然後終止;也可以在程序的生存期內保持活動狀態。

LIBCMT MSVCRT C 運行時庫提供兩個用於創建和終止線程的函數:_beginthread _endthread

_beginthread 函數創建新線程;如果操作成功,則返回線程標識符。線程完成執行時自動終止,或者可通過調用 _endthread 自己終止。

警告   如果要從使用 LIBCMT.LIB 生成的程序調用 C 運行時例程,則必須使用 _beginthread 函數啓動線程。不要使用 Win32 函數 ExitThread CreateThread。如果有一個以上的線程在等待掛起的線程完成它對 C 運行時數據結構的訪問時被阻塞,使用 SuspendThread 會導致死鎖。

_beginthread 函數

_beginthread 函數創建新線程。線程與進程中的其他線程共享進程的代碼和數據段,但是線程具有自己的唯一寄存器值、堆棧空間和當前指令地址。系統給予每個線程 CPU 時間,使進程中的所有線程都可以同時執行。

_beginthread 函數與 Win32 API 中的 CreateThread 函數類似,但有如下差異:

_beginthread 函數使您可以

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章