天天看點

基于Qt的多線程以及互鎖機制

一.在項目中添加一個線程類

基于Qt的多線程以及互鎖機制

1.繼承QThread

基于Qt的多線程以及互鎖機制

2.在Qt 5中是沒有現成的QThread,需要自己手動添加

基于Qt的多線程以及互鎖機制

3.構造函數隐式轉換

基于Qt的多線程以及互鎖機制

4.run()函數

1)線上程中,先執行構造函數,再執行run()函數

2)我這種寫法forever()是Qt中自帶的循環,類似與for .

void robThread::run()
{
    forever
    {
         qDebug()<<"current thread ID************:"<<QThread::currentThreadId();
         if(m_bPause)
         {
          qDebug()<<"this  is  a thread 1111 "<<index;
          //信号在自己的頭檔案中聲明
          emit captured(index);
          sleep(1);
    //      msleep(100);
    //      usleep(1000);
          index++;
           }
          else
           {
              qDebug()<<"this  is break!";
               emit isDone();
              break;

          }
         //信号在自己的頭檔案中聲明

    }
   // exec();
}
void robThread::Stream()
{
    m_bPause = true;
}

void robThread::stop()
{
    m_bPause=false;//判斷一個bool變量
}
           

3)設定bool變量停掉forever()

4)exec()函數,是程式阻塞,等待事件發生,若添加exec()後,程式在關掉視窗前不會終止,等待事件發生,比如按鈕點選事件等。這裡寫線上程run()函數末尾,表示阻塞住線程,等待接受指令,一般都是在等待線程啟動(start)或停止(exit)

5)線程類要在主函數頭檔案中聲明。

基于Qt的多線程以及互鎖機制

5.第二種方式建立線程類

1)首先同上面一樣添加一個類,但不需要繼承QThread

2)在頭檔案中聲明QThread對象以及類對象

private:
    Ui::MainWindow *ui;

    camerathread *m_pcamerathread;
    QThread * m_pCapThread;
    //newclase *m_pnewclase;
           

3)在cpp檔案中将類對象添加進QThread

基于Qt的多線程以及互鎖機制

二.槽函數的三種寫法

1.Qt的槽函數是其引以為傲的操作

1)

槽函數add1(); 信号是signal 按鈕的點選事件

在頭檔案中聲明槽函數以及信号

connect{
觸發信号的對象;//通常是一個按鈕,或是線程的對象
signal觸發信号;//emit()  傳回值隻能是void(),在頭檔案 signal中定義
響應信号的對象;//需要執行功能函數的類的對象
響應槽函數;//與信号的參數一緻,傳回值隻能是void(),public:  、private:   、protected:定義
}
           
//寫法1  SIGNAL()  對應 SLOT()
    connect(ui->signal,SIGNAL(clicked(bool)),this,SLOT(add1()));
           
基于Qt的多線程以及互鎖機制

2)

// 寫法2 
    connect(quitBtn,&QPushButton::clicked,this,&MainWindow::close);
           

3)注意 Q_OBJECT,調用信号槽的宏。(信号槽就是回調函數)

基于Qt的多線程以及互鎖機制

三.執行線程

1.建立好信号槽之後就可以執行相關操作了.

1)開啟線程

2)退出線程 exit()

stop()是上文我自己封裝的槽函數,為了終止forever()循環

void MainWindow::on_pushButton_3_clicked()
{
//判斷線程是否在運作
    if(m_psockeThread->isRunning())
    {
        m_psockeThread->stop();
        if(m_psockeThread)//panduanxianchengshifoucunzai
            m_psockeThread->exit();
        qDebug()<<QString::fromLocal8Bit("1号線程退出");
   }
}
           

3)終止線程

robthread->terminate();
            //wait()+terminate()立即終止線程
            robthread->wait();
           

四.線程互鎖

  • 我寫的案例是兩個四則運算線程,正常執行順序 x1->x2->x3->x4
  • 當不加線程鎖的時候,線程順序打亂運作結果如下
    基于Qt的多線程以及互鎖機制
    1.加了線程鎖之後
    基于Qt的多線程以及互鎖機制
    1)線程1
    基于Qt的多線程以及互鎖機制
    2)線程2
    基于Qt的多線程以及互鎖機制

    3)因為線程執行需要時間,如過快的反複啟動線程會導緻線程混亂

    解決方法:加定時器

void MainWindow::on_pushButton_clicked()
{
    if(index ==0)
    {
      x_time0 = QTime::currentTime().addMSecs(1600); //記錄下目前  +addMSecs  300ms
      th1->start();
      th2->start();
//      th1->wait();
//      th2->wait();
    }
    if(index >0)
    {
        if(QTime::currentTime()>x_time0)
        {
        qDebug()<<"x_time***"<<x_time0;
        x_time0=QTime::currentTime().addMSecs(1600);
        th1->start();
        th2->start();
 //       th1->wait();
//        th2->wait();
        }
        if(QTime::currentTime()<x_time0)
        {
          qDebug()<<"wrong ****************************";
        }
    }
    index++;
}

           
  • 給線程一個3s等待時間,小于該時間不執行線程。
  • #include
    基于Qt的多線程以及互鎖機制