线程同步:关键代码段
关键代码段,也称为临界区,工作在用户方式下。它是指一个小代码段,在代码能够执行前,它必须独占对某些资源的访问权。通常把多线程中访问同一种资源的那部分代码当做关键代码段。
注意:关键代码段不是内核对象,只是用户态下保证资源只能被独立访问的代码加锁。
步骤:先创建关键代码段(本质是一个结构体),再在需要加锁的代码前进入临界区,在结束该段代码后离开临界区,能让其它线程能够进入(同一代码段标识的)临界区。
1.初始化关键代码段InitializeCriticalSection
先声明结构体CRITICAL_SECTION,再将其地址传入
参数:
2.进入关键代码段EnterCriticalSection
参数:
3.退出关键代码段LeaveCriticalSection
参数:
4.删除临界区DeleteCriticalSection
参数:
案例
创建临界区结构体,在关键代码段前加锁,离开后解锁
#include <stdio.h> #include <windows.h> #include <process.h> int iTickets = 5000; CRITICAL_SECTION g_cs;
DWORD WINAPI SellTicketA(void* lpParam) { while (1) { EnterCriticalSection(&g_cs); if (iTickets > 0) { Sleep(1); iTickets--; printf("A remain %d\n", iTickets); LeaveCriticalSection(&g_cs); } else { LeaveCriticalSection(&g_cs); break; } } return 0; } DWORD WINAPI SellTicketB(void* lpParam) { while (1) { EnterCriticalSection(&g_cs); if (iTickets > 0) { Sleep(1); iTickets--; printf("B remain %d\n", iTickets); LeaveCriticalSection(&g_cs); } else { LeaveCriticalSection(&g_cs); break; } } return 0; } int main() { HANDLE hThreadA, hThreadB; hThreadA = CreateThread(NULL, 0, SellTicketA, NULL, 0, NULL); hThreadB = CreateThread(NULL, 0, SellTicketB, NULL, 0, NULL); CloseHandle(hThreadA); CloseHandle(hThreadB); InitializeCriticalSection(&g_cs); Sleep(40000); DeleteCriticalSection(&g_cs); system("pause"); return 0; }
|