C++多线程系列(二)线程互斥

首先了解一下线程互斥的概念,线程互斥说白了就是在进程中多个线程的相互制约,如线程A未执行完毕,其他线程就需要等待!

线程之间的制约关系分为间接相互制约和直接相互制约。

所谓间接相互制约:一个系统中的多个线程必然要共享某种系统资源如共享CPU,共享打印机。间接制约即源于资源共享,线程A在打印的时候其他线程就要等待,否则打印的数据将变得非常混乱。间接相互制约称为互斥,互斥是同步的一种特殊形式

直接相互制约:主要指的是线程之间的一种递进关系,例如线程B运行的条件之一是需要线程A提供的参数,那么在线程A将数据传到线程B之前,线程B都将处于阻塞状态,称为同步。以后再说


(1)临界区,有的称为关键段,是定义在数据段中的一个CRITICAL_SECTION结构,确保在同一时间只有一个线程访问该数据段中的数据。计算机中大多数物理设备,进程中的共享变量等都是临界资源,它们要求被互斥访问,每个进程中访问的临界资源的代码称为临界区

写代码的时候可通过

CRITICAL_SECTION g_csThreadCode;

对临界区进行定义,但是在使用临界区之前首先要对临界区对象进行初始化,其函数原型如下:

InitializeCriticalSection(
    _Out_ LPCRITICAL_SECTION lpCriticalSection
    );


对临界区对象初始化完成后,线程访问临界区数据必须首先调用EnterCriticalSection函数申请进入临界区。在同一时间内,Windows只允许一个线程进入临界区。所以在申请的时候,如果有另一个线程在临界区的话,EnterCriticalSection函数将会一直等待下去,知道其他线程离开临界区才返回。EnterCriticalSection函数定义如下:

EnterCriticalSection(
    _Inout_ LPCRITICAL_SECTION lpCriticalSection
    );


当临界区对象操作完成后使用函数LeaveCriticalSection函数离开临界区,将临界区交还给Windows方便其他线程继续申请使用

LeaveCriticalSection(
    _Inout_ LPCRITICAL_SECTION lpCriticalSection
    );


用完临界区对象,使用DeleteCriticalSection函数将对象删除

DeleteCriticalSection(
    _Inout_ LPCRITICAL_SECTION lpCriticalSection
    );


例:用线程同时访问全局变量并对全局变量进行操作,如果不使用临界区访问,代码如下

#include <stdio.h>
#include <Windows.h>
#include <process.h>

int g_nCount1 = 0;
int g_nCount2 = 0;
BOOL g_bContinue = TRUE;
UINT _stdcall ThreadFun(LPVOID);

int main(int argc, char *argv[])
{
	HANDLE threads[2];

	threads[0] = (HANDLE)_beginthreadex(NULL, 0, ThreadFun, NULL, 0, NULL);
	threads[1] = (HANDLE)_beginthreadex(NULL, 0, ThreadFun, NULL, 0, NULL);

	//等待1秒,结束两个计数线程,关闭句柄
	Sleep(1000);
	g_bContinue = FALSE;
	WaitForMultipleObjects(2, threads, TRUE, INFINITE);
	CloseHandle(threads[0]);
	CloseHandle(threads[1]);

	printf("g_nCount1 = %d\n", g_nCount1);
	printf("g_nCount2 = %d\n", g_nCount2);

	return 0;
}

UINT _stdcall ThreadFun(LPVOID)
{
	while (g_bContinue)
	{
		g_nCount1++;
		g_nCount2++;
	}

	return 0;
}

运行结果截图如下:


  • 8
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值