一.在项目中添加一个线程类
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsICM38FdsYkRGZkRG9lcvx2bjxiNx8VZ6l2cs0TPB5ENJRlT3FFVNBDOsJGcohVYsR2MMBjVtJWd0ckW65UbM5WOHJWa5kHT20ESjBjUIF2X0hXZ0xCMx81dvRWYoNHLrdEZwZ1Rh5WNXp1bwNjW1ZUba9VZwlHdssmch1mclRXY39CXldWYtlWPzNXZj9mcw1ycz9WL49zZuBnLzMDNxEDMwETMxEjNwAjMwIzLc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.png)
1.继承QThread
2.在Qt 5中是没有现成的QThread,需要自己手动添加
3.构造函数隐式转换
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)线程类要在主函数头文件中声明。
5.第二种方式建立线程类
1)首先同上面一样添加一个类,但不需要继承QThread
2)在头文件中声明QThread对象以及类对象
private:
Ui::MainWindow *ui;
camerathread *m_pcamerathread;
QThread * m_pCapThread;
//newclase *m_pnewclase;
3)在cpp文件中将类对象添加进QThread
二.槽函数的三种写法
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()));
2)
// 写法2
connect(quitBtn,&QPushButton::clicked,this,&MainWindow::close);
3)注意 Q_OBJECT,调用信号槽的宏。(信号槽就是回调函数)
三.执行线程
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
- 当不加线程锁的时候,线程顺序打乱运行结果如下 1.加了线程锁之后
基于Qt的多线程以及互锁机制 1)线程1基于Qt的多线程以及互锁机制 2)线程2基于Qt的多线程以及互锁机制 基于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的多线程以及互锁机制