C++&QT 多线程调用全局变量

C++&QT 多线程调用全局变量的解决方案:互斥锁QMutex、信号量QSemaphore

在多线程运行中,各个线程之间难免会对同一个变量进行操作。假设线程thread_A和线程thread_B都会用到全局变量global_C

互斥锁QMutex

QMutex目的是保护对象、结构体或者代码块,让其一次仅在一个线程里可以使用。

int global_C = 6;
void method_1()
{
	global_C *= 5;
	global_C /= 4;
}
void method_2()
{
	global_C += 3;
	global_C -= 2;
}

假设线程A调用method_1(),线程B调用method_2()。
依次调用两个线程:

// 当先运行线程A,后运行线程B,结果是:
// method_1()
	global_C *= 5;		//global_C 此时是30
	global_C /= 4;		//global_C 此时是7
	
// method_2()
	global_C += 3;		//global_C 此时是10
	global_C -= 2;		//global_C 此时是8

同时调用两个线程:

//当线程A和线程B同时运行时,其中一种结果可能是:
// 线程A运行method_1()
	global_C *= 5;		//global_C 此时是30
// 此时,极有可能操作系统让线程A进入休眠状态,使得线程B运行method_2()
	global_C += 3;		//global_C 此时是33
	global_C -= 2;		//global_C 此时是31
// 线程A运行method_1()
	global_C /= 4;		//global_C 此时是7

//当线程A和线程B同时运行时,其中一种结果也有可能是:
// 线程A运行method_1()
	global_C *= 5;		//global_C 此时是30
// 此时,极有可能操作系统让线程A进入休眠状态,使得线程B运行method_2()
	global_C += 3;		//global_C 此时是33
// 此时,极有可能操作系统让线程B进入休眠状态,使得线程A运行method_1()
	global_C /= 4;		//global_C 此时是8
// 线程B运行method_2()
	global_C -= 2;		//global_C 此时是6
	

此时,可以发现,当两个线程同时调用时,结果时混乱的。我们用QMutex来规避这种风险,任何时候,只有一个线程可以修改变量global_C ,从而保证结果的正确性。当线程A调用lock()时,线程B尝试调用lock()时将会阻塞,直到线程A调用unlock():

QMutex mutex;
int global_C = 6;
void method_1()
{
	mutex.lock();
	global_C *= 5;
	global_C /= 4;
	mutex.unlock();
}
void method_2()
{
	mutex.lock();
	global_C += 3;
	global_C -= 2;
	mutex.unlock();
}

信号量QSemaphore

QSemaphore是QMutex的泛化,QMutex只能锁一次,而QSemaphore可以多次获取信号量。类比来看,QMutex保护单个数量的同一个资源,而QSemaphore用来保护多个数量的同一个资源(有点抽象,可以简单的理解为把一个资源拷贝了好多份,但实际情况可能并不是这样)。

available() 返回当前可用的资源数量
acquire(int n) 尝试获取n个数量的同一个资源,如果n>available(),程序将会阻塞,直到获取到足够数量。
release(int n) 释放n个数量的资源。这里的释放指的是拿出n个数量的资源来使用,这样可以满足n个线程来使用这个资源(备注:这个函数也可以被当作"create" 资源来使用)。
tryAcquire(int n) 尝试获取n个数量的同一个资源,如果n<available(),获取n个资源,并返回true;如果n>available(),不获取任何资源,并返回false。

QSemaphore sem(10);			//创建并初始化保护n个同一资源,10 == sem.available()
sem.acquire(3);				//获取3个同一资源,7 == sem.available()
sem.acquire(6);				//获取6个同一资源,1 == sem.available()
sem.release(4);				//释放4个同一资源,5 == sem.available()
sem.release(5);				//"create" 5 new resources,10 == sem.available()
sem.tryAcquire(11);			//返回false,10 == sem.available()
sem.tryAcquire(2);			//返回true,8 == sem.available()
  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

撒欢打滚的人儿

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值