QThread 类提供不依赖平台的管理线程的方法,如果要设计多线程程序,一般是从 QThread继承定义一个线程类,在自定义线程类里进行任务处理。 qt拥有一个GUI线程 ,该线程阻塞式监控窗体,来自任何用户的操作都会被gui捕获到,并处理;如果有耗时的任务,不推荐在GUI中处理.怎么办?? 创建线程,交给线程去耗时! 一个QThread类的对象管理一个线程。该线程包括 执行函数体 ,这是线程执行的主要代码部分。函数体中有一个死循环 ,用于保持线程的持续运行,直到条件满足。线程私有空间 ,每个线程都有自己的独立数据和堆栈空间。QThread 提供了完整的线程功能,并且内置了一个虚函数 run() 用于处理线程任务。我们可以通过重写  run() 方法来定义线程的具体行为。编写线程的具体方法为继承QThread并重写run()函数。最好是直接定义一个线程类(实际上也这样做)。 GUI线程和控件访问 :只有主GUI线程可以访问和操作窗体上的控件。如果其他线程尝试直接访问这些控件,会导致程序崩溃。为了在线程中更新UI,可以使用信号和槽机制。class  MyThread  :  public  QThread { 
    Q_OBJECT
signals: 
    void  updateUI ( int  value) ; 
public : 
    void  run ( )  override  { 
        for  ( int  i =  0 ;  i <  10 ;  ++ i)  { 
            emit updateUI ( i) ;  
            QThread :: sleep ( 1 ) ; 
        } 
    } 
} ; 
connect ( ptMyThread,  & MyThread:: updateUI,  this ,  & MainWindow:: updateUIFunction) ; 
线程的启动和停止使用start()和stop()函数即可。这也是可以捕获的信号,可以用来连接槽函数,不过要加上ed。 出现了此类错误error: undefined reference to `vtable for myThread ,那么就将该错误发生的头文件和函数体文件移除该工程,然后再添加进来。 代码举例 结构体通信 QMutex buflock; 
buflock. lock ( ) ; 
buflock. unlock ( ) ; 
 
  结构体要在使用该结构体的线程中声明,定义在外面,方便其他线程使用或声明,当然互斥锁也要有哈。   
  一般通过构造函数传入或写出数据。   
  在重写run()函数里有while循环,或者是死循环,具体情况而定   
  当然也要有休眠函数,给其他线程一点时间执行嘛。   
  代码举例  
# ifndef  RETHREAD_H # define  RETHREAD_H # include <QThread> # include <QMutex> struct  msg_struct { 
    int  temp; 
    int  shidu; 
    char  des[ 128 ] ; 
} ; 
class  thread_write : public  QThread { 
public : 
    thread_write ( ) ; 
    thread_write ( struct  msg_struct  * pmsg, QMutex * pMutex) ; 
    ~ thread_write ( ) ; 
    void  run ( )  override ; 
private : 
    struct  msg_struct  * pShareMsg; 
    QMutex * pMutex; 
} ; 
class  thread_read : public  QThread { 
public : 
    thread_read ( struct  msg_struct  * pmsg, QMutex * pMutex) ; 
    thread_read ( ) ; 
    ~ thread_read ( ) ; 
    void  run ( )  override ; 
private : 
    struct  msg_struct  * pShareMsg; 
    QMutex * pMutex; 
} ; 
# endif  # include  "rethread.h" # include <QDebug> :: thread_write ( ) 
{ 
} 
thread_write:: thread_write ( msg_struct * pmsg,  QMutex * pMutex) 
{ 
    pShareMsg =  pmsg; 
    this -> pMutex= pMutex; 
} 
thread_write :: ~ thread_write ( ) 
{ 
} 
void  thread_write:: run ( ) 
{ 
    char  ch =  'A' ; 
    while ( 1 ) { 
        pMutex-> lock ( ) ; 
        for ( int  i=  0 ; i< 127 ; i++ ) { 
            pShareMsg-> des[ i] = ch; 
            if ( i% 20 == 0 ) { 
                QThread :: sleep ( 1 ) ; 
            } 
        } 
        pMutex-> unlock ( ) ; 
        QThread :: msleep ( 10 ) ; 
        ch++ ; 
    } 
} 
thread_read:: thread_read ( msg_struct * pmsg,  QMutex * pMutex) 
{ 
    pShareMsg =  pmsg; 
    this -> pMutex =  pMutex; 
} 
thread_read:: thread_read ( ) 
{ 
} 
thread_read :: ~ thread_read ( ) 
{ 
} 
void  thread_read:: run ( ) 
{ 
    QThread :: sleep ( 1 ) ; 
    while ( 1 ) { 
        pMutex-> lock ( ) ; 
        qDebug ( ) << "thread read" << __func__ << " " << pShareMsg-> des; 
        pMutex-> unlock ( ) ; 
        QThread :: sleep ( 5 ) ; 
    } 
} 
# ifndef  WIDGET_H # define  WIDGET_H # include "rethread.h" # include  <QWidget> namespace  Ui {  class  Widget ;  } 
QT_END_NAMESPACE
class  Widget  :  public  QWidget { 
    Q_OBJECT
public : 
    Widget ( QWidget * parent =  nullptr ) ; 
    ~ Widget ( ) ; 
private : 
    Ui:: Widget * ui; 
    struct  msg_struct  * pShareMsg; 
    QMutex * pMutex; 
    thread_read * pThreadRead; 
    thread_write * pThreadWrite; 
} ; 
# endif  # include  "widget.h" # include  "ui_widget.h" Widget :: Widget ( QWidget * parent) 
    :  QWidget ( parent) 
    ,  ui ( new  Ui:: Widget) 
{ 
    ui-> setupUi ( this ) ; 
    pShareMsg =  new  struct  msg_struct ; 
    pMutex =  new  QMutex; 
    pThreadRead  =  new  thread_read ( pShareMsg, pMutex) ; 
    pThreadWrite =  new  thread_write ( pShareMsg, pMutex) ; 
    pThreadWrite-> start ( ) ; 
    pThreadRead-> start ( ) ; 
} 
Widget :: ~ Widget ( ) 
{ 
    delete  ui; 
} 
 
信号和槽 在一个线程中定义一个信号,然后将其连接到另一个线程中的槽函数,通过信号的触发来调用槽函数。这是Qt中最常用的线程间通信方法。 这之中有一个线程铁定是GUI线程。才可以使用信号和槽 例如 值得注意的是不要在GUI程序中加入sleep睡眠之类的代码,容易造成程序崩溃。 线程同步是指在多线程环境中,协调线程之间的执行顺序和数据共享,确保线程以预期的方式访问共享资源。同步的主要目的是避免竞争条件(race conditions)和数据不一致性。 互斥量可以保证在任意时刻只有一个线程可以访问共享资源,从而避免竞争条件和数据不一致性。 定义一把互斥锁 
QMutex * pMutex; 
pMutex =  new  QMutex; 
上锁,如果互斥量已经被其他线程锁定,当前线程将被阻塞 ,直到互斥量可用。 pMutex. lock ( ) ; 
解锁,访问共享资源后,线程需要释放互斥量的锁,以便其他线程可以访问该资源。 pMutex. unlock ( ) ; 
尝试上锁,函数tryLock()尝试锁定一个互斥量,如果成功锁定就返回true,如果其他线程已经锁定了这个互斥量就返回false,不等待。有参数则等待。 pMutex. try_Lock ( ) ; 
基于读写锁(Read-Write Lock)的线程同步是一种高效的同步机制,适用于读多写少的场景。与互斥锁不同,读写锁允许多个 线程同时读取共享资源,但在写入资源时,只允许一个 线程进行写操作,这样可以提高程序的并发性能。 定义一把读写锁 
QReadWriteLock * pRWLock; 
pRWLock =  new  QReadWriteLock; 
pRWLock.lockForRead(); //以只读方式锁定资源,如果有其他线程以写入方式锁定资源,这个函数会被阻塞 pRWLock.lockForWrite(); //以写入方式锁定资源,如果其他线程以读或写方式锁定资源,这个函数会被阻塞pRWLock.unlock();//解锁 它们可以在前面加上try,如tryLockForRead();表示尝试以读的方式锁上资源,括号内的参数可以表示尝试多少毫秒 QWaitCondition 提供了一种改进的线程同步方法,QWaitCondition 通过与 QMutex 或 QReadWriteLock 结合使用,可以使一个线程在满足一定条件时通知其他多个线程,使其他多个线程及时进行响应,这样比只使用互斥量或读写锁效率要高一些。 定义 
QMutex mutex; 
QReadWriteLock readWriteLock; 
QWaitCondition condition; 
bool wait(QMutex *lockedMutex, unsigned long time = ULONG_MAX) ,释放lockMutex这个互斥信号量。线程进入休眠,等待被唤醒,默认无限等待。若被唤醒则返回true;若超时则返回false。bool wait(QReadWriteLock *lockedReadWriteLock, unsigned long time = ULONG_MAX) ,释放lockedReadWriteLock这个读写锁,并让线程进入等待状态直到被唤醒或者超时。默认情况下,无限期等待。若被唤醒则返回true;若超时则返回false。void wakeAll() :唤醒所有处于等待状态的线程。唤醒顺序不确定,由操作系统的调度策略决定。void wakeOne() :唤醒一个处于等待状态的线程。具体唤醒哪个线程不确定,由操作系统的调度策略决定。信号量(QSemaphore)是用于控制多个线程对共享资源的访问的同步原语。它是一种计数器,允许你在特定时间允许多个线程同时访问某个资源。信号量可以用来限制访问的线程数。 使用方法 方法名 描述 参数 返回值 构造函数 QSemaphore(int initialCount = 1, int maxCount = 1)创建一个信号量,初始计数和最大计数。 initialCount:初始计数值maxCount:最大计数值无 基本方法 acquire(int num = 1)获取 num 个资源,若资源不足,线程阻塞。 num:需要获取的资源数量无 release(int num = 1)释放 num 个资源,增加信号量的计数器。 num:需要释放的资源数量无 带超时的方法 acquire(int num, unsigned long timeout = ULONG_MAX)获取 num 个资源,直到超时。 num:需要获取的资源数量timeout:超时时间(毫秒)bool:成功获取资源返回 true,超时返回 false检查方法 tryAcquire(int num = 1)尝试获取 num 个资源,若资源不足则立即返回。 num:需要获取的资源数量bool:成功获取资源返回 true,否则返回 falseavailable() const返回可用资源的数量。 int:可用资源数量其他方法 setCount(int count)设置信号量的计数器值。 count:新的计数值无 maximumCount() const返回信号量的最大值。 int:最大值currentCount() const返回当前信号量的计数值。 int:当前计数值
 
代码示例 # include  <QCoreApplication>  # include  <QThread>           # include  <QSemaphore>        # include  <QDebug>            semaphore ( 3 ) ; 
class  Worker  :  public  QThread { 
public : 
    void  run ( )  override  {  
        
        if  ( semaphore. tryAcquire ( 1 ,  1000 ) )  {  
            qDebug ( )  <<  "Thread"  <<  QThread :: currentThreadId ( )  <<  "acquired a resource." ;  
            QThread :: sleep ( 2 ) ;  
            qDebug ( )  <<  "Thread"  <<  QThread :: currentThreadId ( )  <<  "finished working." ;  
            semaphore. release ( ) ;  
        }  else  { 
            qDebug ( )  <<  "Thread"  <<  QThread :: currentThreadId ( )  <<  "could not acquire a resource within timeout." ;  
        } 
        
        qDebug ( )  <<  "Current available resources:"  <<  semaphore. available ( ) ;  
        semaphore. setCount ( 5 ) ;  
        qDebug ( )  <<  "Max count:"  <<  semaphore. maximumCount ( ) ;  
        qDebug ( )  <<  "Current count:"  <<  semaphore. currentCount ( ) ;  
    } 
} ; 
int  main ( int  argc,  char  * argv[ ] )  { 
    QCoreApplication a ( argc,  argv) ;  
    
    Worker worker1,  worker2,  worker3,  worker4,  worker5; 
    
    worker1. start ( ) ; 
    worker2. start ( ) ; 
    worker3. start ( ) ; 
    worker4. start ( ) ; 
    worker5. start ( ) ; 
    
    worker1. wait ( ) ; 
    worker2. wait ( ) ; 
    worker3. wait ( ) ; 
    worker4. wait ( ) ; 
    worker5. wait ( ) ; 
    return  a. exec ( ) ;  
} 
QThread::sleep(int sec);//个方法使当前线程休眠指定的秒数。 QThread::msleep(int msec);//这个方法使当前线程休眠指定的毫秒数。 QThread::usleep(int usec);//这个方法使当前线程休眠指定的微秒数。