美文网首页
(十)QT专题-使用QT自身的线程类

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

作者: GoodTekken | 来源:发表于2023-02-16 13:48 被阅读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\n"<<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()函数会执行。

    相关文章

      网友评论

          本文标题:(十)QT专题-使用QT自身的线程类

          本文链接:https://www.haomeiwen.com/subject/gmpqkdtx.html