QT5 信号与槽研究
----------------------------------------
一个主窗口给多个工作线程发信号,线程的槽函数是如何工作的?
是并行的还是串行的?
通过研究知道, 它是串行工作的. 而且纵然工作线程没有启动,它也可以工作.
各个槽函数只是signal 依次调用各线程下的槽函数而以.
signal-slot 机制跟线程没有关系,只跟对象有关系.
下面贴上我的研究代码,里面还有其它thread 的相关知识.
例如:线程是并行运行的,如何停止线程和重启线程等.可以参考注释.
ls *.h|xargs cat
#ifndef _CLOCK_THREAD_H
#define _CLOCK_THREAD_H
#include <QThread>
class ClockThread: public QThread
{
Q_OBJECT
public:
ClockThread(int id,QObject *parent = nullptr);
~ClockThread() {}
void run() ;
void set_thread_runing(bool thread_runing);
signals:
void sigReady(int);
private slots:
void slotWork();
private:
bool m_thread_runing;
int m_id;
};
#endif
#ifndef _MAINW_H
#define _MAINW_H
#include <QMainWindow>
class ClockThread;
class MainWindow :public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent=0);
~MainWindow();
signals:
void startWork();
private slots:
void slot_updateClock(int);
private:
ClockThread *clock_thread1;
ClockThread *clock_thread2;
int ready[2];
};
#endif
ls *.cpp |xargs cat
#include "clockthread.h"
#include <sys/time.h>
long gettime_us()
{
struct timeval tv;
gettimeofday(&tv,NULL);
return tv.tv_sec*1000000+tv.tv_usec;
}
ClockThread::ClockThread(int id,QObject *parent)
:QThread(parent)
{
m_id=id;
}
void ClockThread::run()
{
while(m_thread_runing) // 线程是并行运行的.
{
long time=gettime_us();
printf("in thread> id:%d, run time:%ld\n",m_id,time/1000);
sleep(1);
}
}
void ClockThread::set_thread_runing(bool thread_runing)
{
m_thread_runing = thread_runing;
}
void ClockThread::slotWork() // slot 是串行工作的. 受mainw 的signal 调用
{
long time1=gettime_us();
printf("thread slot> id:%d,receive working signal, time:%ld\n",m_id,time1/1000);
sleep(1);
long time2=gettime_us();
printf("thread slot> id:%d, work ready time:%ld\n",m_id,time2/1000);
emit sigReady(m_id);
}
#include <QApplication>
#include "mainw.h"
int main(int argc,char *argv[])
{
QApplication app(argc,argv);
MainWindow mainw;
mainw.show();
return app.exec();
}
#include "mainw.h"
#include "clockthread.h"
MainWindow::MainWindow(QWidget *parent):QMainWindow(parent)
{
clock_thread1 = new ClockThread(1,this);
connect(clock_thread1, SIGNAL(sigReady(int)), this, SLOT(slot_updateClock(int)));
connect(this,SIGNAL(startWork()),clock_thread1, SLOT(slotWork()));
clock_thread2 = new ClockThread(2,this);
connect(clock_thread2, SIGNAL(sigReady(int)), this, SLOT(slot_updateClock(int)));
connect(this,SIGNAL(startWork()),clock_thread2, SLOT(slotWork()));
ready[0]=0;
ready[1]=0;
clock_thread1->set_thread_runing(true);
clock_thread2->set_thread_runing(true);
// clock_thread1->start(); //thread 不运行,signal slot 照样运行
// clock_thread2->start();
emit startWork();
}
MainWindow::~MainWindow()
{
//如果析构函数为空,当然会有
//QThread: Destroyed while thread is still running
//已放弃
//如果不停止线程而wait, 会卡死.
clock_thread1->set_thread_runing(false);
clock_thread2->set_thread_runing(false);
//停止了线程,必须等待线程结束, 否则也会有
//QThread: Destroyed while thread is still running
//已放弃
clock_thread1->wait();
clock_thread2->wait();
//这句delete 倒是可有可无的,不会内存泄露,此处不加
//MainWindow 的析构中会调用delete, 因为clock_thread 是MainWindow 的子对象
delete clock_thread1;
delete clock_thread2;
}
extern long gettime_us();
void MainWindow::slot_updateClock(int id)
{
long time=gettime_us();
printf("main receive work ready signal.id:%d,time:%ld\n",id,time/1000);
ready[id-1]=1;
if(ready[0]==1 && ready[1]==1)
{
clock_thread1->set_thread_runing(false);
clock_thread2->set_thread_runing(false);
clock_thread1->wait();
clock_thread2->wait();
ready[0]=0; //初始化
ready[1]=0;
clock_thread1->set_thread_runing(true);
clock_thread2->set_thread_runing(true);
clock_thread1->start();
clock_thread2->start();
emit startWork(); //再一次启动工作
}
}
运行结果如下,时间是毫秒(ms)
./test_thread
thread slot> id:1,receive working signal, time:1647053331018
thread slot> id:1, work ready time:1647053332019
main receive work ready signal.id:1,time:1647053332019
thread slot> id:2,receive working signal, time:1647053332019
thread slot> id:2, work ready time:1647053333019
main receive work ready signal.id:2,time:1647053333019
thread slot> id:1,receive working signal, time:1647053333019
in thread> id:1, run time:1647053333019
in thread> id:2, run time:1647053333019
thread slot> id:1, work ready time:1647053334019
main receive work ready signal.id:1,time:1647053334019
thread slot> id:2,receive working signal, time:1647053334019
in thread> id:1, run time:1647053334020
in thread> id:2, run time:1647053334020
thread slot> id:2, work ready time:1647053335020
main receive work ready signal.id:2,time:1647053335020
in thread> id:2, run time:1647053335020
in thread> id:1, run time:1647053335020
in thread> id:1, run time:1647053336020
thread slot> id:1,receive working signal, time:1647053336020
in thread> id:2, run time:1647053336021
thread slot> id:1, work ready time:1647053337021
main receive work ready signal.id:1,time:1647053337021
thread slot> id:2,receive working signal, time:1647053337021
in thread> id:1, run time:1647053337021
in thread> id:2, run time:1647053337021
in thread> id:1, run time:1647053338021
in thread> id:2, run time:1647053338021
thread slot> id:2, work ready time:1647053338021
代码下载链接: