因为公司的业务需求,需要用到线程来解决程序的阻塞问题,特意学习了一下,这里分享给大家。
线程是操作系统能够进行运算调度的最小单位,被包含在进程之中,是进程中的实际运作单位。
一条线程实则指进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务。
QT 线程的实现有两种方式,一种是直接继承 QThread 类,重写 run() 函数,还有一种是继承 QObject 类,通过 QThread 类方法进行挂载,下面是两种方式的实现步骤:
实现方式一:直接继承 QThread 类,重构 run() 函数
class TestThread: public QThread{
Q_OBJECT
public:
explicit TestThread(QThread* parent = nullptr);
~TestThread();
private:
};
class TestThread: public QThread{
Q_OBJECT
public:
explicit TestThread(QThread* parent = nullptr);
~TestThread();
protected:
void run();
private:
};
TestThread::TestThread(QThread* parent): QThread (parent){
//需要执行的操作不要放这里
}
TestThread::~TestThread(){}
void TestThread::run(){
//在这里放需要执行的操作
}
TestThread* testThread = new TestThread();
testThread -> start();
到了这里,线程就完成了启动,如果需要关闭线程的话,一共有三种操作,一种是使用 quit() 退出,该操作退出后不执行任何操作,相当于 exit(0);一种是使用 exit(int returnCode = 0) 退出,该操作会间接调用 QEventLoop::exec() 函数,然后返回 returnCode 变量;最后一种是使用信号槽进行关联挂载,当某项操作被执行后,线程直接退出,一般用的比较多的用法connect(this, &QObject::deleteLater, testThread, &QThread::finished);
。
这是官方提供的案例:
class WorkerThread : public QThread
{
Q_OBJECT
void run() override {
QString result;
/* ... here is the expensive or blocking operation ... */
emit resultReady(result);
}
signals:
void resultReady(const QString &s);
};
void MyObject::startWorkInAThread()
{
WorkerThread *workerThread = new WorkerThread(this);
connect(workerThread, &WorkerThread::resultReady, this, &MyObject::handleResults);
connect(workerThread, &WorkerThread::finished, workerThread, &QObject::deleteLater);
workerThread->start();
}
实现方式二:继承 QObject 类,通过 QThread 类方法进行挂载
class TestThread: public QObject{
Q_OBJECT
public:
explicit TestThread(QObject* parent = nullptr);
~TestThread();
private:
};
class TestThread: public QObject{
Q_OBJECT
public:
explicit TestThread(QObject* parent = nullptr);
~TestThread();
public slots:
void toDo();
private:
};
TestThread::TestThread(QObject* parent): QObject(parent){
//需要执行的操作不要放这里
}
TestThread::~TestThread(){}
void TestThread::toDo(){
//在这里放需要执行的操作
}
QThread* test = new QThread();
TestThread* testThread = new TestThread();
void startToDo();
connect(test, &QThread::finished, testThread, &QObject::deleteLater);
connect(this, signal(startToDo()), testThread, &TestThread::toDo);
testThread -> moveToThread(test);
test -> start();
emit startToDo();
这是官方提供的案例:
class Worker : public QObject
{
Q_OBJECT
public slots:
void doWork(const QString ¶meter) {
QString result;
/* ... here is the expensive or blocking operation ... */
emit resultReady(result);
}
signals:
void resultReady(const QString &result);
};
class Controller : public QObject
{
Q_OBJECT
QThread workerThread;
public:
Controller() {
Worker *worker = new Worker;
worker->moveToThread(&workerThread);
connect(&workerThread, &QThread::finished, worker, &QObject::deleteLater);
connect(this, &Controller::operate, worker, &Worker::doWork);
connect(worker, &Worker::resultReady, this, &Controller::handleResults);
workerThread.start();
}
~Controller() {
workerThread.quit();
workerThread.wait();
}
public slots:
void handleResults(const QString &);
signals:
void operate(const QString &);
};
学习分享,一起成长!接触QT的时间不长,目前差不多快三个月了,有不足之处,欢迎大佬指出来,我会进行更正。有问题可以发送邮件至 [email protected] ,不定时上线查收。