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:編程 |