標籤:

Win32多線程程序設計-同步控制

Win32多線程程序設計-同步控制

先看一下傳說中的printf

#include "windows.h"#include "stdio.h" DWORD WINAPI Thread1_Proc(PVOID pvParam){ while(1) { printf("Hello,"); Sleep(50); }} DWORD WINAPI Thread2_Proc(PVOID pvParam){ while(1) { printf("World!
"); Sleep(50); }} int main(int argc, char* argv[]){ DWORD nID; CreateThread(NULL, 0, Thread1_Proc, NULL, 0, NULL); CreateThread(NULL, 0, Thread2_Proc, NULL, 0, NULL); while(1) { ; } return 0;}

其運行結果如下:

Win32之中最容易使用的一個同步機制就是critical section。所謂critical section意指一小塊「用來處理一份被共享之資源」的程序代碼。這裡所謂的資源,並不是指來自.RES(資源文件),而是廣義地指一塊內存、一個數據結構、一個文件或任何具有「使用之排他性」的東西。也就是說,資源每一次同一時間內只能被一個線程處理。

在Win32程序中可以為每一個需要保護的資源聲明一個CRITICAL_SECTION類型的變數。這個變數扮演紅綠燈的角色,讓同一時間內只有一個線程進入critical section。

Critical section並不是核心對象,因此沒有所謂的handle,它和核心對象不同,它存在於進場的內存空間中,不需要像create這樣的API函數來獲得一個critical section handle 而是應該將一個類型為CRITICAL_SECTION的局部變數初始化,方法是調用InitializeCriticalSection()

當用完critical section時,必須調用DeleteCriticalSection()清除它。

一旦critical section被初始化,每一個線程就可以進入其中,只要它通過了EnterCriticalSection()

當線程準備離開critical section時,必須調用LeaveCriticalSection()

所以上面的printf經過改進可得如下:

#include "windows.h"#include "stdio.h" CRITICAL_SECTION cs;DWORD WINAPI Thread1_Proc(PVOID pvParam){ while(1) { EnterCriticalSection(&cs); printf("Hello,"); LeaveCriticalSection(&cs); Sleep(50); }} DWORD WINAPI Thread2_Proc(PVOID pvParam){ while(1) { EnterCriticalSection(&cs); printf("World!
"); LeaveCriticalSection(&cs); Sleep(50); }} int main(int argc, char* argv[]){ DWORD nID; InitializeCriticalSection(&cs); CreateThread(NULL, 0, Thread1_Proc, NULL, 0, NULL); CreateThread(NULL, 0, Thread2_Proc, NULL, 0, NULL); while(1) { ; } DeleteCriticalSection(&cs); return 0;}

其結果有改進---hello以及wrold不會被拆分

所以在此基礎上進而控制hello以及world次數問題,改進如下:

#include "windows.h"#include "stdio.h" bool flag;CRITICAL_SECTION cs;DWORD WINAPI Thread1_Proc(PVOID pvParam){ while(1) { while (flag==1); EnterCriticalSection(&cs); printf("Hello,"); LeaveCriticalSection(&cs); flag=1; Sleep(50); }} DWORD WINAPI Thread2_Proc(PVOID pvParam){ while(1) { while (flag==0); EnterCriticalSection(&cs); printf("World!
"); LeaveCriticalSection(&cs); flag=0; Sleep(50); }} int main(int argc, char* argv[]){ DWORD nID; InitializeCriticalSection(&cs); CreateThread(NULL, 0, Thread1_Proc, NULL, 0, NULL); CreateThread(NULL, 0, Thread2_Proc, NULL, 0, NULL); while(1) { ; } DeleteCriticalSection(&cs); return 0;}

其運行結果如下:

推薦閱讀:

即使不當碼農,你也要知道的15種編程語言
如何為列表裡的字典(元組)進行排序
雜文筆記: 「堅持」的背後
Arduino編程風格(譯)

TAG:編程 |