QMutex & QWaitCondition 小记!

用惯了Boost的mutex和Condition,突然发现QT的互斥锁与信号量跟Boost的这么神似! 所以今儿将QT的互斥与信号量做个小抄,方便后续查看!

同时,记录一下先前对condition的使用一直比较模糊的地方顺便也做个笔记!

// QThreadAndMutexLocker.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"

#include <iostream>
#include <QtCore\qthread>
#include <QtCore\qmutex>
#include <QtCore\qwaitcondition>

QMutex g_mutex;
QWaitCondition g_cond;


class CA : public QThread
{
public:
	CA(){ start(); }
	~CA(){ wait(); }

private:
	void run()
	{
		for (size_t i = 0; i < 10; i++)
		{
			QThread::msleep(100);
			QMutexLocker l(&g_mutex);
			std::cout << "CA locked and call wakeAll() " << i << std::endl;

			g_cond.wakeAll();

			/*以下注释部分证明g_cond.wakeAll()只是发出信号,但没有解锁,wakeAll下面代码部分仍是CA的锁范围之内
			注:因此g_cond.wakeAll调用之后,CB线程虽拿到信号但直到CA线程释放锁才行。
			结论:情况1:g_cond.wakeAll()在CA的锁范围之内, CA线程调用wakeAll(),CB拿到信号并准备解锁,CA释放锁,CB拿到锁
			     情况2:g_cond.wakeAll()在CA的锁范围之外, CA线程调用wakeAll(),CB拿到信号并准备解锁,CA与CB产生抢锁
			    因此:g_cond.wakeAll()即可在锁范围内出现也可出现在锁范围外,但是,场景1的明显效率高于场景2。如果在CA
				的锁范围外调用一次sleep,能更能有效的确保CB能第1时间拿到锁。
			*/
			//for (size_t i = 0; i < 10; i++)
			//{
			//	std::cout << " CA : " << i << std::endl;
			//	QThread::msleep(1000);
			//}
		}

		QThread::msleep(1);  //等待1ms,让CA线程挂机,确保CB线程能即时拿到锁.
	}
};

class CB : public QThread
{
public:
	CB(){ start(); }
	~CB(){ wait(); }

private:
	void run()
	{

		for (size_t i = 0; i < 10; i++)
		{
			QMutexLocker l(&g_mutex);

			std::cout << " CB locked, and waitting condition!" << std::endl;

			g_cond.wait(&g_mutex); // 1: wait时,将调用g_mutex.unlock(); 2:等到信号时,将调用g_mutex.lock();

			for (size_t i = 0; i < 10; i++)
			{
				std::cout << " CB : " << i << std::endl;
				QThread::msleep(1000);
			}
		}
	}
};

int _tmain(int argc, _TCHAR* argv[])
{
	{
		CB cb;
		QThread::msleep(2000);
		CA ca;
	}

	getchar();

	return 0;
}



`QWaitCondition`和`QMutex`是Qt库中的同步机制,它们通常一起用于线程间的协作,尤其是在需要等待特定条件后再继续执行的情况下。下面是一个简单的例子: ```cpp #include &lt;QThread&gt; #include &lt;QMutex&gt; #include &lt;QWaitCondition&gt; class WorkerThread : public QThread { public: explicit WorkerThread(QMutex&amp; mutex, QWaitCondition&amp; condition) : mutex(mutex), condition(condition) {} private: void run() override { // 这里模拟一些耗时的操作 for (int i = 0; i &lt; 5; ++i) { qDebug() &lt;&lt; &quot;Worker Thread is doing some work...&quot;; // 加锁 mutex.lock(); // 模拟完成工作并通知主线程 if (someConditionIsMet()) { qDebug() &lt;&lt; &quot;Work completed, signaling main thread.&quot;; condition.wakeOne(); // 醒通知一个等待的线程 } // 释放锁 mutex.unlock(); qSleep(100); // 等待100毫秒 } } QMutex&amp; mutex; QWaitCondition&amp; condition; signals: void workCompleted(); }; // 主线程 class MainThread : public QObject { public slots: void startWorking() { QMutexLocker locker(&amp;mutex); workerThread.start(); // 在这里等待工作完成 while (!workerThread.isFinished()) { condition.wait(mutex); } workerThread.workCompleted(); // 收到信号后处理 } private: QMutex mutex; WorkerThread workerThread; }; int main(int argc, char *argv[]) { QApplication app(argc, argv); MainThread mainThread; mainThread.startWorking(); return app.exec(); } ``` 在这个例子中,`WorkerThread`在一个单独的线程中运行,它持有`QMutex`,当工作完成后会唤醒主线程。主线程通过`QWaitCondition`等待`workCompleted()`信号,只有当`WorkerThread`的工作结束才会解除等待。这展示了如何在多线程环境下使用`QWaitCondition`和`QMutex`确保线程安全。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值