VC++ 多线程同步实例
?
?
臨界區
#include "stdafx.h" #include<windows.h> #include<iostream> using namespace std;int number = 1; //定義全局變量 CRITICAL_SECTION Critical; //定義臨界區句柄unsigned long __stdcall ThreadProc1(void* lp) {while (number < 100){EnterCriticalSection(&Critical);cout << "thread 1 :"<<number << endl;++number;Sleep(100);LeaveCriticalSection(&Critical);}return 0; }unsigned long __stdcall ThreadProc2(void* lp) {while (number < 100){EnterCriticalSection(&Critical);cout << "thread 2 :"<<number << endl;++number;Sleep(100);LeaveCriticalSection(&Critical);}return 0; }int _tmain(int argc, _TCHAR* argv[]) {InitializeCriticalSection(&Critical); //初始化臨界區對象CreateThread(NULL, 0, ThreadProc1, NULL, 0, NULL);CreateThread(NULL, 0, ThreadProc2, NULL, 0, NULL);Sleep(10 * 1000);system("pause");return 0; }運行結果:?
?
事件
事件(Event)是WIN32提供的最靈活的線程間同步方式,事件可以處于激發狀態(signaled or true)或未激發狀態(unsignal or false)。根據狀態變遷方式的不同,事件可分為兩類:?
(1)手動設置:這種對象只可能用程序手動設置,在需要該事件或者事件發生時,采用SetEvent及ResetEvent來進行設置。?
(2)自動恢復:一旦事件發生并被處理后,自動恢復到沒有事件狀態,不需要再次設置。
使用”事件”機制應注意以下事項:?
(1)如果跨進程訪問事件,必須對事件命名,在對事件命名的時候,要注意不要與系統命名空間中的其它全局命名對象沖突;?
(2)事件是否要自動恢復;?
(3)事件的初始狀態設置。
由于event對象屬于內核對象,故進程B可以調用OpenEvent函數通過對象的名字獲得進程A中event對象的句柄,然后將這個句柄用于ResetEvent、SetEvent和WaitForMultipleObjects等函數中。此法可以實現一個進程的線程控制另一進程中線程的運行,例如:
HANDLE hEvent=OpenEvent(EVENT_ALL_ACCESS,true,"MyEvent"); ResetEvent(hEvent);代碼示例:
#include "stdafx.h" #include<windows.h> #include<iostream> using namespace std;int number = 1; //定義全局變量 HANDLE hEvent; //定義事件句柄unsigned long __stdcall ThreadProc1(void* lp) {while (number < 100){WaitForSingleObject(hEvent, INFINITE); //等待對象為有信號狀態cout << "thread 1 :" << number << endl;++number;Sleep(100);SetEvent(hEvent);}return 0; }unsigned long __stdcall ThreadProc2(void* lp) {while (number < 100){WaitForSingleObject(hEvent, INFINITE); //等待對象為有信號狀態cout << "thread 2 :" << number << endl;++number;Sleep(100);SetEvent(hEvent);}return 0; }int _tmain(int argc, _TCHAR* argv[]) {CreateThread(NULL, 0, ThreadProc1, NULL, 0, NULL);CreateThread(NULL, 0, ThreadProc2, NULL, 0, NULL);hEvent = CreateEvent(NULL, FALSE, TRUE, L"event");Sleep(10 * 1000);system("pause");return 0; }運行結果:?
?
?
信號量
信號量是維護0到指定最大值之間的同步對象。信號量狀態在其計數大于0時是有信號的,而其計數是0時是無信號的。信號量對象在控制上可以支持有限數量共享資源的訪問。
信號量的特點和用途可用下列幾句話定義:?
(1)如果當前資源的數量大于0,則信號量有效;?
(2)如果當前資源數量是0,則信號量無效;?
(3)系統決不允許當前資源的數量為負值;?
(4)當前資源數量決不能大于最大資源數量。
創建信號量
函數原型為:
| 1 2 3 4 5 | HANDLE?CreateSemaphore ( ?? PSECURITY_ATTRIBUTE psa,?//信號量的安全屬性 ??LONG?lInitialCount,?//開始時可供使用的資源數 ??LONG?lMaximumCount,?//最大資源數 ???PCTSTR?pszName);?????//信號量的名稱 |
釋放信號量
通過調用ReleaseSemaphore函數,線程就能夠對信標的當前資源數量進行遞增,該函數原型為:
| 1 2 3 4 5 | BOOL?WINAPI ReleaseSemaphore( ?? HANDLE?hSemaphore,???//要增加的信號量句柄 ?? LONG?lReleaseCount,?//信號量的當前資源數增加lReleaseCount ?? LPLONG?lpPreviousCount??//增加前的數值返回 ???); |
打開信號量
和其他核心對象一樣,信號量也可以通過名字跨進程訪問,打開信號量的API為:
| 1 2 3 4 5 | HANDLE?OpenSemaphore ( ?? DWORD?fdwAccess,??????//access ?? BOOL?bInherithandle,??//如果允許子進程繼承句柄,則設為TRUE ?? PCTSTR?pszName??//指定要打開的對象的名字 ??); |
代碼示例:
#include "stdafx.h" #include<windows.h> #include<iostream> using namespace std;int number = 1; //定義全局變量 HANDLE hSemaphore; //定義信號量句柄unsigned long __stdcall ThreadProc1(void* lp) {long count;while (number < 100){WaitForSingleObject(hSemaphore, INFINITE); //等待信號量為有信號狀態cout << "thread 1 :" << number << endl;++number;Sleep(100);ReleaseSemaphore(hSemaphore, 1, &count);}return 0; }unsigned long __stdcall ThreadProc2(void* lp) {long count;while (number < 100){WaitForSingleObject(hSemaphore, INFINITE); //等待信號量為有信號狀態cout << "thread 2 :" << number << endl;++number;Sleep(100);ReleaseSemaphore(hSemaphore, 1, &count);}return 0; }int _tmain(int argc, _TCHAR* argv[]) {hSemaphore = CreateSemaphore(NULL, 1, 100, L"sema");CreateThread(NULL, 0, ThreadProc1, NULL, 0, NULL);CreateThread(NULL, 0, ThreadProc2, NULL, 0, NULL);Sleep(10 * 1000);system("pause");return 0; }運行結果:?
?
互斥量
采用互斥對象機制。 只有擁有互斥對象的線程才有訪問公共資源的權限,因為互斥對象只有一個,所以能保證公共資源不會同時被多個線程訪問。互斥不僅能實現同一應用程序的公共資源安全共享,還能實現不同應用程序的公共資源安全共享。
代碼示例:
#include "stdafx.h" #include<windows.h> #include<iostream> using namespace std;int number = 1; //定義全局變量 HANDLE hMutex; //定義互斥對象句柄unsigned long __stdcall ThreadProc1(void* lp) {while (number < 100){WaitForSingleObject(hMutex, INFINITE);cout << "thread 1 :" << number << endl;++number;Sleep(100);ReleaseMutex(hMutex);}return 0; }unsigned long __stdcall ThreadProc2(void* lp) {while (number < 100){WaitForSingleObject(hMutex, INFINITE);cout << "thread 2 :" << number << endl;++number;Sleep(100);ReleaseMutex(hMutex);}return 0; }int _tmain(int argc, _TCHAR* argv[]) {hMutex = CreateMutex(NULL, false, L"mutex"); //創建互斥對象CreateThread(NULL, 0, ThreadProc1, NULL, 0, NULL);CreateThread(NULL, 0, ThreadProc2, NULL, 0, NULL);Sleep(10 * 1000);system("pause");return 0; }運行結果:?
?
?
?
總結
以上是生活随笔為你收集整理的VC++ 多线程同步实例的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 二十二、标志寄存器与栈(代码设计安全,与
- 下一篇: MySQL数据的备份与还原实现步骤