(十)QT专题-使用QT自身的线程类

内容分享4天前发布
0 0 0

Qt提供了QThread类以进行多任务处理。与多任务处理一样,Qt提供的线程可以做到单个线程做不到的事情。例如,在网络应用程序中,可以使用线程处理多种连接器。QThread类提供了一个与平台无关的方式来管理线程。第一用一个类继承QThread类,然后重新改写QThread类的虚函数run()。只需要实例该类,然后调用函数start(),就可以开启新的多线程(run()函数被自动调用)。除此之外,还有一种方法,即继承QObject类,然后调用moveToThread()函数开启一个线程槽函数,把要花费大量时间计算的代码放入该线程槽函数中。
我们主要来看第一种方法。注意:只执行了run()函数才是新的线程在执行,所有复杂的逻辑都应该放在run()函数里面。当run()函数运行完毕后,该线程的声明周期就结束了。run()函数的原型声明如下:
[virtual protected] void QThread::run()
我们要做的就是把新线程要执行的操作放到run()函数(线程函数)中。除了run()函数之外,还有其他QThread成员函数有时会用到。

1.QThread类的基本使用

引入头文件#include<QThread>

#include "MainWindow.h"

#include <QApplication>
#include <unistd.h>  //for sleep
#include <iostream>
#include <QThread>

using namespace std;
#define handle_error_en(en,msg) do {errno = en;perror(msg);exit(EXIT_FAILURE);}while (0);
#define PTHREAD_NUM 2


class MyThread:public QThread
{
public:
    virtual void run();
};

void MyThread::run()
{
    for(int count = 0;count<10;count++)
    {
        sleep(1);
        qDebug("ping %d",count);
    }
}

int main(int argc, char *argv[])
{
//    QApplication a(argc, argv);
//    MainWindow w;
//    w.show();

    MyThread thA;
    thA.start();
    thA.wait();
    cout<<"thread A is over."<<endl;
    sleep(5);
    pthread_exit(NULL); // the main thread will exit, but main process will  not
    cout<<"main thread has exited,this line will not run
"<<endl;
//    return a.exec();
}

Output:

ping 0
ping 1
ping 2
ping 3
ping 4
ping 5
ping 6
ping 7
ping 8
ping 9
thread A is over.

2.线程间通信

Qt线程间(数据)通信主要有两种方式:
(1)使用共享内存,也就是使用两个线程都能够共享的变量(如全局变量),这样两个线程都能够访问和修改该变量,从而达到共享数据的目的。
(2)使用信号槽(Signal/Slot>)机制,把数据从一个线程传递到另外一个线程。

第一种方法在各个编程语言中都普遍使用,而第二种方法是QT特有的。这里我们主要介绍第二种方法。我们来看一个例子,子线程发送信号(信号参数是一个整数)给主线程,主线程得到这个信号后显示在便签控件上,子线程每隔一秒就累加一次整数,相当于一个计数器。主线程也可以发送信号给子线程,把计数器重置为0。这一来一往就实现了子线程和主线程的相互通信。示例程序虽小,但是功能与原理和大示例是一样的。

TestThread.h

#ifndef TESTTHREAD_H
#define TESTTHREAD_H

#include <unistd.h>  //for sleep
#include <iostream>
#include <QThread>

class TestThread:public QThread
{
    Q_OBJECT
public:
    TestThread(QObject *parent = 0);

protected:
    void run();

signals:
    void TestSignal(int);

public slots:
    void ResetSlot();

private:
    int number;
};

#endif // TESTTHREAD_H

TestThread.cpp

#include "TestThread.h"

TestThread::TestThread(QObject *parent):QThread(parent)
{
    number = 0;
}

void TestThread::run()
{
    while(1)
    {
        number++;
        emit TestSignal(number);
        sleep(1);
    }
}

void TestThread::ResetSlot()
{
    number = 0;
    emit TestSignal(number);
}

//线程开始:
TestThread* thA = new TestThread();
//connetc()  //绑定好相关的信号连接
//connect()  //
thA->start();  //

第一从QThread类继承了一个自定义类MyThread,并实现了run()函数。然后在main()主函数中创建MyThread类的对象thA,并调用QThread类的start()函数,该函数将会启动子线程,即run()函数会执行。

© 版权声明

相关文章

暂无评论

您必须登录才能参与评论!
立即登录
none
暂无评论...