多线程—临界区:
解决多个线程同时防访一个变量的解决方法。
#include<stdio.h>
#include<stdlib.h>
#include<Windows.h>
//#define N 65 //临界区最多只能开辟 64 个线程
#define N 64
int num = 0;
CRITICAL_SECTION cs1;
CRITICAL_SECTION cs2; //定义临界区,临界区是结构体
DWORD WINAPI add(void *p)
{
//这样使用临界区,效率高。
EnterCriticalSection(&cs1); //进入临界区
for (int i = 0; i < 10000; i++)
{
//这样使用临界区效率低
//EnterCriticalSection(&cs1); //进入临界区
num++;
//LeaveCriticalSection(&cs1); //离开临界区
}
LeaveCriticalSection(&cs1); //离开临界区
}
DWORD WINAPI sub(void *p)
{
for (int i = 0; i < 10000; i++)
{ //这样使用临界区效率低
EnterCriticalSection(&cs2); //进入临界区
num--;
LeaveCriticalSection(&cs2); //离开临界区
}
}
//这儿使用了线程同步
void main01()
{
HANDLE hd[N]; //线程启动时,
for (int i = 0; i < N; i++)
{
hd[i] = CreateThread(NULL, 0, add, NULL, 0, NULL);
WaitForSingleObject(hd[i], INFINITE);
}
//WaitForMultipleObjects(N, hd, TRUE, INFINITE);
//等待所有线程结束,代码这样写,结束也不正确,因为数据共享没有解决,要配合每个线程结束,才能正确 WaitForSingleObject(hd[i], INFINITE);
printf("%d\n", num);
system("pause");
}
//这儿使用了临界区
void main()
{
//临界区一定要初始化,C 不会自动初始化
InitializeCriticalSection(&cs1); //初始化结构体(临界区)
InitializeCriticalSection(&cs2);
{
HANDLE hd[N]; //线程启动时,
for (int i = 0; i < N; i++)
{
hd[i] = CreateThread(NULL, 0, add, NULL, 0, NULL);
}
WaitForMultipleObjects(N, hd, TRUE, INFINITE); //等待所有线程结束
printf("%d\n", num);
}
{
HANDLE hd[N]; //线程启动时,
for (int i = 0; i < N; i++)
{
hd[i] = CreateThread(NULL, 0, sub, NULL, 0, NULL);
}
WaitForMultipleObjects(N, hd, TRUE, INFINITE); //等待所有线程结束
printf("%d\n", num);
}
DeleteCriticalSection(&cs1); //释放,因为初始化的临界区结构体在堆上,所以在释放掉
DeleteCriticalSection(&cs2);
system("pause");
}