实现思路
QThread 类简介 : QThread
是 Qt 中用于多线程编程的基础类。可以通过继承 QThread
并重写 run()
方法来创建自定义的线程逻辑。新线程的执行从 run()
开始,调用 start()
方法启动线程。 掷骰子的多线程应用程序 : 创建一个 DiceThread
类继承自 QThread
,在 run()
方法中模拟掷骰子操作,并通过信号将结果发送出去。 线程同步 : 线程同步的概念 :确保多个线程之间协调操作,避免数据竞争和不一致性。基于互斥量的线程同步 :使用 QMutex
确保在同一时间只有一个线程可以访问共享资源。基于读写锁的线程同步 :使用 QReadWriteLock
,允许多个读线程同时访问资源,但写线程独占资源。基于条件等待的线程同步 :使用 QWaitCondition
与 QMutex
结合,允许线程等待某个条件满足。基于信号量的线程同步 :使用 QSemaphore
控制对资源的访问数量。
代码示例
1. QThread 类简介和掷骰子的多线程应用程序
# include <QtWidgets/QApplication>
# include <QtCore/QThread>
# include <QtCore/QRandomGenerator>
# include <QtCore/QDebug>
# include <QtCore/QMutex>
# include <QtCore/QReadWriteLock>
# include <QtCore/QWaitCondition>
# include <QtCore/QSemaphore> class DiceThread : public QThread { Q_OBJECT
signals: void resultReady ( int result) ; protected : void run ( ) override { while ( ! isInterruptionRequested ( ) ) { int diceValue = QRandomGenerator :: global ( ) -> bounded ( 1 , 7 ) ; emit resultReady ( diceValue) ; msleep ( 1000 ) ; } }
} ; int main ( int argc, char * argv[ ] ) { QApplication app ( argc, argv) ; DiceThread diceThread; QObject :: connect ( & diceThread, & DiceThread:: resultReady, [ ] ( int result) { qDebug ( ) << "Dice result: " << result; } ) ; diceThread. start ( ) ; QThread :: sleep ( 10 ) ; diceThread. requestInterruption ( ) ; diceThread. wait ( ) ; return app. exec ( ) ;
} # include "main.moc"
2. 基于互斥量的线程同步
# include <QtWidgets/QApplication>
# include <QtCore/QThread>
# include <QtCore/QRandomGenerator>
# include <QtCore/QDebug>
# include <QtCore/QMutex> class SharedData {
public : int value = 0 ; QMutex mutex;
} ; class IncrementThread : public QThread {
public : IncrementThread ( SharedData * data) : data ( data) { } protected : void run ( ) override { for ( int i = 0 ; i < 1000 ; ++ i) { data-> mutex. lock ( ) ; ++ data-> value; data-> mutex. unlock ( ) ; msleep ( 1 ) ; } } private : SharedData * data;
} ; int main ( int argc, char * argv[ ] ) { QApplication app ( argc, argv) ; SharedData sharedData; IncrementThread thread1 ( & sharedData) ; IncrementThread thread2 ( & sharedData) ; thread1. start ( ) ; thread2. start ( ) ; thread1. wait ( ) ; thread2. wait ( ) ; qDebug ( ) << "Final value: " << sharedData. value; return app. exec ( ) ;
} # include "main.moc"
3. 基于读写锁的线程同步
# include <QtWidgets/QApplication>
# include <QtCore/QThread>
# include <QtCore/QRandomGenerator>
# include <QtCore/QDebug>
# include <QtCore/QReadWriteLock> class SharedData {
public : int value = 0 ; QReadWriteLock lock;
} ; class ReadThread : public QThread {
public : ReadThread ( SharedData * data) : data ( data) { } protected : void run ( ) override { for ( int i = 0 ; i < 1000 ; ++ i) { data-> lock. lockForRead ( ) ; qDebug ( ) << "Read value: " << data-> value; data-> lock. unlock ( ) ; msleep ( 1 ) ; } } private : SharedData * data;
} ; class WriteThread : public QThread {
public : WriteThread ( SharedData * data) : data ( data) { } protected : void run ( ) override { for ( int i = 0 ; i < 100 ; ++ i) { data-> lock. lockForWrite ( ) ; ++ data-> value; data-> lock. unlock ( ) ; msleep ( 10 ) ; } } private : SharedData * data;
} ; int main ( int argc, char * argv[ ] ) { QApplication app ( argc, argv) ; SharedData sharedData; ReadThread reader1 ( & sharedData) ; ReadThread reader2 ( & sharedData) ; WriteThread writer ( & sharedData) ; reader1. start ( ) ; reader2. start ( ) ; writer. start ( ) ; reader1. wait ( ) ; reader2. wait ( ) ; writer. wait ( ) ; qDebug ( ) << "Final value: " << sharedData. value; return app. exec ( ) ;
} # include "main.moc"
4. 基于条件等待的线程同步
# include <QtWidgets/QApplication>
# include <QtCore/QThread>
# include <QtCore/QRandomGenerator>
# include <QtCore/QDebug>
# include <QtCore/QMutex>
# include <QtCore/QWaitCondition> class SharedData {
public : int value = 0 ; QMutex mutex; QWaitCondition condition; bool ready = false ;
} ; class ProducerThread : public QThread {
public : ProducerThread ( SharedData * data) : data ( data) { } protected : void run ( ) override { QRandomGenerator gen; for ( int i = 0 ; i < 10 ; ++ i) { QThread :: msleep ( 1000 ) ; data-> mutex. lock ( ) ; data-> value = gen. bounded ( 1 , 100 ) ; data-> ready = true ; data-> condition. wakeOne ( ) ; data-> mutex. unlock ( ) ; } } private : SharedData * data;
} ; class ConsumerThread : public QThread {
public : ConsumerThread ( SharedData * data) : data ( data) { } protected : void run ( ) override { while ( true ) { data-> mutex. lock ( ) ; if ( ! data-> ready) { data-> condition. wait ( & data-> mutex) ; } qDebug ( ) << "Consumed value: " << data-> value; data-> ready = false ; data-> mutex. unlock ( ) ; } } private : SharedData * data;
} ; int main ( int argc, char * argv[ ] ) { QApplication app ( argc, argv) ; SharedData sharedData; ProducerThread producer ( & sharedData) ; ConsumerThread consumer ( & sharedData) ; consumer. start ( ) ; producer. start ( ) ; return app. exec ( ) ;
} # include "main.moc"
5. 基于信号量的线程同步
# include <QtWidgets/QApplication>
# include <QtCore/QThread>
# include <QtCore/QRandomGenerator>
# include <QtCore/QDebug>
# include <QtCore/QSemaphore> class SharedResource {
public : QSemaphore semaphore; void useResource ( ) { semaphore. acquire ( ) ; qDebug ( ) << "Using resource..." ; QThread :: msleep ( 100 ) ; semaphore. release ( ) ; }
} ; class UserThread : public QThread {
public : UserThread ( SharedResource * resource) : resource ( resource) { } protected : void run ( ) override { for ( int i = 0 ; i < 10 ; ++ i) { resource-> useResource ( ) ; } } private : SharedResource * resource;
} ; int main ( int argc, char * argv[ ] ) { QApplication app ( argc, argv) ; SharedResource resource; resource. semaphore. release ( 3 ) ; UserThread thread1 ( & resource) ; UserThread thread2 ( & resource) ; UserThread thread3 ( & resource) ; thread1. start ( ) ; thread2. start ( ) ; thread3. start ( ) ; thread1. wait ( ) ; thread2. wait ( ) ; thread3. wait ( ) ; return app. exec ( ) ;
} # include "main.moc"
代码解释
1. QThread 类简介和掷骰子的多线程应用程序
DiceThread 类 : 继承 QThread
并在 run()
中模拟掷骰子操作,使用 QRandomGenerator
生成 1 到 6 的随机数。 通过 resultReady
信号将结果发送出去,在主线程中连接该信号并打印结果。
2. 基于互斥量的线程同步
SharedData 类 : IncrementThread 类 : 每次循环对 value
加 1 前先加锁,加 1 后解锁,确保同一时间只有一个线程修改 value
。
3. 基于读写锁的线程同步
SharedData 类 : 包含一个 value
变量和 QReadWriteLock
。 ReadThread 类 : 读线程使用 lockForRead()
锁定,读取 value
后解锁。 WriteThread 类 : 写线程使用 lockForWrite()
锁定,修改 value
后解锁,写线程独占资源,读线程可同时读。
4. 基于条件等待的线程同步
SharedData 类 : 包含 value
、QMutex
、QWaitCondition
和 ready
标志。 ProducerThread 类 : 生产者线程生成数据,使用 wakeOne()
唤醒等待的消费者。 ConsumerThread 类 : 消费者线程等待 ready
标志,使用 wait()
等待,一旦有数据可用,打印并重置 ready
。
5. 基于信号量的线程同步
SharedResource 类 : 包含 QSemaphore
,初始释放 3 个资源。 UserThread 类 : 每次使用资源前先 acquire()
资源,使用后 release()
资源,确保最多 3 个线程同时使用资源。
使用说明
对于每个示例,将代码保存为 main.cpp
文件。 确保 .pro
文件包含 QT += core widgets
以及 CONFIG += c++11
。 编译并运行程序,观察不同线程同步机制的效果。