QT各种锁及线程同步应用

一.概述

1.在Qt中,主要有以下几种锁的类型:

(1)QMutex(互斥锁):是最常见的锁类型,用于实现简单的互斥访问。可以通过lock()和unlock()手动控制锁的加锁和解锁。

(2)QMutexLocker:是一个RAII类,用于简化对QMutex的加锁和解锁过程。在创建QMutexLocker对象时,会自动加锁,离开作用域时会自动解锁,确保资源在合适的时候被解锁,避免忘记解锁或异常导致未解锁的情况。

(3)QReadWriteLock(读写锁):用于实现读写分离的锁机制,允许多个线程同时读取共享资源,但只有一个线程可以进行写入操作。可以通过lockForRead()和lockForWrite()手动控制读取锁和写入锁。

QReadLocker和QWriteLocker:是QReadWriteLock的RAII类,用于简化对QReadWriteLock的加读锁和加写锁过程。在创建QReadLocker或QWriteLocker对象时,会自动加读锁或加写锁,离开作用域时会自动解锁,确保资源在合适的时候被解锁。

(4)QSemaphore(信号量):允许控制对共享资源的并发访问数量。可以通过acquire()和release()手动控制资源的获取和释放。

(5)QWaitCondition(条件变量):用于线程间的等待和唤醒,允许一个线程等待特定条件的发生,并在其他线程满足条件时发出信号。

总体来说,Qt提供了丰富的锁机制来帮助开发者实现线程安全的并发编程。选择合适的锁类型取决于具体的并发场景和资源访问需求。在使用锁时,一定要小心避免死锁和竞态条件等问题,确保线程间安全的共享资源访问。

同时,使用RAII类(如QMutexLocker、QReadLocker、QWriteLocker)可以简化锁的管理,减少出错的可能性。

2.其他线程同步机制

QThread::wait()

QThread::wait() 是Qt提供的一个线程同步机制,可以用于等待一个线程完成执行。调用该函数会使当前线程阻塞,直到指定的线程完成执行为止。

二.代码示例

1.QMutex(互斥锁)的例子:

#include <QMutex>

QMutex mutex;

int count = 0;

for (int i = 0; i < 1000; ++i) {

mutex.lock();

++count;

mutex.unlock();

}

qDebug() << "Final count:" << count;

2.QMutexLocker的例子:

#include <QCoreApplication>

#include <QMutex>

#include <QMutexLocker>

#include <QDebug>

void run() {

QMutex mutex;

QMutexLocker locker(&mutex);

for (int i = 0; i < 1000; ++i) {

++sharedResource;

}

qDebug() << "Thread" << QThread::currentThreadId() << "finished. Current count:" << sharedResource;

}

int main(int argc, char *argv[])

{

QCoreApplication a(argc, argv);

run();

return a.exec();

}

3.QReadWriteLock(读写锁)的例子:

#include <QCoreApplication>

#include <QReadWriteLock>

#include <QDebug>

#include <QThread>

#include <QMutexLocker>

#include <QRandomGenerator>

// 假设的共享资源

class SharedData {

public:

SharedData() : data(0) {}

void read() const {

// 读取操作,这里只是打印信息

qDebug() << "Thread" << QThread::currentThreadId() << "is reading the data:" << data;

}

void write(int newValue) {

// 写入操作,这里设置新值并打印信息

data = newValue;

qDebug() << "Thread" << QThread::currentThreadId() << "wrote the data:" << data;

}

int data;

};

// 全局的共享数据和读写锁

SharedData sharedData;

QReadWriteLock rwLock;

void readTask() {

// 使用 QReadLocker 自动管理读锁

QReadLocker locker(&rwLock);

sharedData.read();

}

void writeTask(int value) {

// 使用 QWriteLocker 自动管理写锁

QWriteLocker locker(&rwLock);

sharedData.write(value);

}

int main(int argc, char *argv[]) {

QCoreApplication a(argc, argv);

// 创建并启动读取线程

QThread readThread;

QObject::connect(&readThread, &QThread::started, readTask);

readThread.start();

// 等待读取线程开始

readThread.sleep(1); // 示例中简单等待,实际应用中可能需要更复杂的同步机制

// 在主线程中执行写入任务

writeTask(27);

// 等待读取线程完成

readThread.wait();

return a.exec();

}

4.QSemaphore(信号量)的例子:

#include <QCoreApplication>

#include <QSemaphore>

#include <QDebug>

#include <QThread>

int main(int argc, char *argv[])

{

QCoreApplication a(argc, argv);

QSemaphore semaphore(1); // 初始信号量计数为1

// 创建两个线程,模拟同时访问共享资源

QThread thread1, thread2;

QObject::connect(&thread1, &QThread::started, [&]() {

semaphore.acquire();

qDebug() << "Thread 1: Accessing shared resource...";

QThread::sleep(2); // 模拟资源访问

semaphore.release();

qDebug() << "Thread 1: Done!";

});

QObject::connect(&thread2, &QThread::started, [&]() {

semaphore.acquire();

qDebug() << "Thread 2: Accessing shared resource...";

QThread::sleep(2); // 模拟资源访问

semaphore.release();

qDebug() << "Thread 2: Done!";

});

thread1.start();

thread2.start();

thread1.wait();

thread2.wait();

return a.exec();

}

5.QWaitCondition(条件变量)的例子:

#include <QCoreApplication>

#include <QMutex>

#include <QWaitCondition>

#include <QDebug>

#include <QThread>

int main(int argc, char *argv[])

{

QCoreApplication a(argc, argv);

QMutex mutex;

QWaitCondition condition;

bool isReady = false;

// 等待线程

QThread waitThread;

QObject::connect(&waitThread, &QThread::started, [&]() {

QMutexLocker locker(&mutex);

qDebug() << "Waiting thread: Waiting for condition...";

condition.wait(&mutex);

qDebug() << "Waiting thread: Condition signaled!";

});

// 发送信号线程

QThread signalThread;

QObject::connect(&signalThread, &QThread::started, [&]() {

QThread::sleep(2);

QMutexLocker locker(&mutex);

isReady = true;

qDebug() << "Signaling thread: Condition is ready!";

condition.wakeOne();

});

waitThread.start();

signalThread.start();

waitThread.wait();

signalThread.wait();

return a.exec();

}

三.其他线程同步机制

1.QThread::wait()

QThread::wait() 是Qt提供的一个线程同步机制,可以用于等待一个线程完成执行。调用该函数会使当前线程阻塞,直到指定的线程完成执行为止。

以下是一个使用QThread::wait()的示例:

#include <QThread>

#include <QDebug>

class Thread : public QThread

{

public:

void run() override

{

qDebug() << "Thread started";

sleep(1);

qDebug() << "Thread finished";

}

};

int main(int argc, char *argv[])

{

Thread thread;

thread.start();

qDebug() << "Waiting for thread to finish...";

thread.wait();

qDebug() << "Thread finished, exiting...";

}

在这个示例中,我们创建了一个Thread线程,并调用start()函数启动它。然后,我们调用QThread::wait()函数等待该线程完成执行。该函数会使当前线程阻塞,直到指定的线程完成执行为止。

相关推荐
清风~徐~来1 小时前
【Redis】类型补充
数据库·redis·缓存
代码探秘者1 小时前
【Redis从入门到精通实战文章汇总】
数据库·redis·缓存
weixin_748877001 小时前
【Redis实战:缓存与消息队列的应用】
数据库·redis·缓存
····懂···2 小时前
PostgreSQL 技术峰会,为您打造深度交流优质平台
数据库·postgresql
2301_802502335 小时前
哈工大计算机系统2025大作业——Hello的程序人生
数据库·程序人生·课程设计
Alan3169 小时前
Qt 中,设置事件过滤器(Event Filter)的方式
java·开发语言·数据库
TDengine (老段)9 小时前
TDengine 集群容错与灾备
大数据·运维·数据库·oracle·时序数据库·tdengine·涛思数据
Lao A(zhou liang)的菜园10 小时前
高效DBA的日常运维主题沙龙
运维·数据库·dba
迪迦不喝可乐11 小时前
mysql知识点
数据库·mysql
不太可爱的大白11 小时前
MySQL 事务的 ACID 四大特性及其实现原理
数据库·mysql