本文已参与「新人创作礼」活动,一起开启掘金创作之路。
前言
最近用到一个sdk启动有一个成员函数在使用的时候会阻塞GUI线程导致执行该成员函数过后,再操作主页面会导致程序卡顿甚至胡乱操作会导致程序崩溃,然后为了解决这个问题我第一个想到的肯定是多线程实现,晚上的多线程教程帖子很多但是都是再多线程的类的run函数中写具体的实现,都无法实现将一个类中的成员函数移到线程中执行最终我根据晚上现有的线程最终实验出以下的方法解决这个问题。 文章1:blog.csdn.net/bukajiushan… 文章2:blog.csdn.net/an505479313…
思路
首先实现基本的继承线程类用来调用qthread run,然后我们使用静态成员函数的方式在线程类中调用主类中的成员函数,但是这里需要注意的一点就是静态成员函数(又叫类共享函数)无法直接调用主类中的私有变量,所以我们需要将需要丢进线程中的成员函数用到的私有变量包装一个接口。
代码实现
mythread.cpp
#ifndef MYTHREAD_H
#define MYTHREAD_H
#include <QThread>
#include "test.h"
class myThread : public QThread
{
Q_OBJECT
public:
explicit myThread(QObject *parent = nullptr);
void run();
void setSleepNum(int s);
signals:
void isDone(int iRet);
private:
int sleepNum = 0;
};
#endif // MYTHREAD_H
mythread.h
#include "mythread.h"
myThread::myThread(QObject *parent) :
QThread(parent)
{
}
void myThread::run()
{
test::test_sleep(sleepNum); // 记得包含要调用的头文件
emit isDone(1); // 这里可以做标志来返回执行其他类成员函数过后的返回值
}
void myThread::setSleepNum(int s)
{
this->sleepNum = s;
}
主类中的调用
static void test_sleep(int s); // 该类的声明
// 要丢到线程中执行的类
void test::test_sleep(int s)
{
qDebug() << "线程开始执行了 " << endl;
QThread::sleep(s);// 该函数中不能调用该类的私有变量和函数
}
// 调用线程
void test::on_btn_openThread_clicked()
{
myThread *thread = new myThread(this);
thread.setSleepNum(2);// 设置执行函数要用到的参数
connect(thread,&myThread::isDone,this,[=](int iRet)
{
thread->quit();
thread->wait();
if (iRet) qDebug() << "线程执行完毕" << endl;
});
thread->start();
}
最后效果和总结
线程虽然是很好用,但是不是在任何地方都适用,个人觉得在使用多线程的前提一定是某个算法、函数、循环影响了其他函数或者界面的时候,不要为了用多线程而用多线程,这样并不会显得你的代码能力有多强,更多的是会让别人看到你的程序复杂难懂,对于团队合作来讲这是非常大的影响。