版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/brunomarss/article/details/82984116
/*
* 临界区:线程同步方式,用于限制“公用代码”一次只能被一个线程使用
* 使用示例:全局变量
* 使用限制:只能用于同一个进程中的线程,不能跨进程同步
*/
#include <windows.h>
#include <stdio.h>
#include <process.h>
#include <stdlib.h>
// 定义一个临界区
CRITICAL_SECTION g_cs;
// 线程函数
unsigned __stdcall ThreadFunc(LPVOID lpVoid)
{
EnterCriticalSection(&g_cs); // 进入临界区,如果有其他线程则等待
printf("%s\n", lpVoid); // 受保护代码
LeaveCriticalSection(&g_cs); // 退出临界区,其他线程可以进来
return TRUE;
}
int main()
{
// 初始化临界区
InitializeCriticalSection(&g_cs);
HANDLE ht1, ht2, ht3;
char s1[128] = "first";
char s2[128] = "second";
char s3[128] = "third";
// 创建线程
ht1 = (HANDLE)_beginthreadex(NULL, 0, ThreadFunc, s1, 0, NULL);
ht2 = (HANDLE)_beginthreadex(NULL, 0, ThreadFunc, s2, 0, NULL);
ht3 = (HANDLE)_beginthreadex(NULL, 0, ThreadFunc, s3, 0, NULL);
// 线程作为核心对象的引用计数减1(创建线程之后引用计数为2)
// 即创建线程之后一共有2个handle对应到此对象,一个为线程本身,一个为创建线程的线程
// 减1之后,线程结束时引用计数再次减1,系统将删除线程内核对象
// 若没有减一,则引用计数在线程结束后仍为1,程序结束运行后线程内核对象被系统回收,
// 而在程序运行过程中已经造成了内存泄漏的问题
// 关闭线程句柄
CloseHandle(ht1);
CloseHandle(ht2);
CloseHandle(ht3);
// 主线程等待子线程结束
WaitForSingleObject(ht1, INFINITE);
WaitForSingleObject(ht2, INFINITE);
WaitForSingleObject(ht3, INFINITE);
// 删除临界区
DeleteCriticalSection(&g_cs);
system("pause");