临界区指的是一个访问共用资源(例:全局变量)的程序片段,该共用资源无法同时被多个线程访问的特性。有多个线程试图同时访问临界区,那么在有一个线程进入后其他所有试图访问此临界区的线程将被挂起,并一直持续到进入临界区的线程离开。临界区在被释放后,其他线程可以继续抢占,并以此达到用原子方式操作共享资源的目的。
临界区在使用时以CRITICAL_SECTION结构对象保护共享资源,并分别用EnterCriticalSection()和LeaveCriticalSection()函数去标识和释放一个临界区。所用到的CRITICAL_SECTION结构对象必须经过InitializeCriticalSection()的初始化后才能使用,而且必须确保所有线程中的任何试图访问此共享资源的代码都处在此临界区的保护之下。否则临界区将不会起到应有的作用,共享资源依然有被破坏的可能。
一:步骤
创建临界区对象:CRITICAL_SECTION critical
初始化临界区:InitializeCriticalSection(&critical)
进入临界区:EnterCriticalSection(&critical)
释放临界区:LeaveCriticalSection(&critical)
二:代码实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55
| /******************************************************** Copyright (C), 2016-2018, FileName: t12 Author: woniu201 Created: 2018/10/23 Description: 线程同步-临界区 ********************************************************/ #include <iostream> #include <Windows.h> using namespace std; volatile int number = 1; CRITICAL_SECTION critical; //临界区句柄 DWORD CALLBACK ThreadFun1(LPVOID pParam) { while (1) { EnterCriticalSection(&critical); cout << "Thread1:" << number++ << endl; if (number >= 1000) { break; } LeaveCriticalSection(&critical); } return 0; } DWORD CALLBACK ThreadFun2(LPVOID pParam) { while (1) { EnterCriticalSection(&critical); cout << "Thread2:" << number++ << endl; LeaveCriticalSection(&critical); if (number >= 1000) { break; } } return 0; } int main() { InitializeCriticalSection(&critical); CreateThread(NULL, 0, ThreadFun1, NULL, 0, NULL); CreateThread(NULL, 0, ThreadFun2, NULL, 0, NULL); getchar(); return 1; }
|