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