成都网站建设设计

将想法与焦点和您一起共享

(73课)Qt中的多线程编程(一)

一、Qt中通过QThread直接支持多线程

创新互联公司是专业的硚口网站建设公司,硚口接单;提供成都网站建设、网站制作,网页设计,网站设计,建网站,PHP网站建设等专业做网站服务;采用PHP框架,可快速的进行硚口网站开发网页制作和功能扩展;专业做搜索引擎喜爱的网站,专业的做网站团队,希望更多企业前来合作!

    1、QThread是一个跨平台的多线程解决方案

    2、QThread以简洁易用的方式实现多线程编程

注意:1、Qt中的线程以对象的形式被创建和使用

      2、每一个线程对应着一个QThread对象

QThread这个类,是一个线程父类,我们需要继承这个QThread类。

QThread类,提供了一组成员函数。一个线程是以一个对象的形式来表现出来,所以说,我们创建一个

线程的时候,实际上就是创建了一个这个QThread线程类的对象

一个线程对应一个QThread对象

二、QThread中的关键成员函数

1、void run()

    线程体函数,用于定义线程功能(执行流),是线程的入口函数。

2、void start()

    启动函数,在操作系统中真正创建出一个线程后,将线程入口地址设置为run函数

3、void terminate()

    强制结束线程(不推荐)

三、自定义一个线程类

class MyThread : public QThread
{
protected:    //保护,被保护的成员函数,不能直接被外界访问,但是可以被子类直接访问
        void run()    //重写QThread类中的run成员函数,来实现我们线程体逻辑
        {
            for ( int i = 0; i < 5; i++)
            {
                qDebug() << objectName() <

可以说是三个线程上面的,因为还包含了主线程,三个线程是并行执行的。宏观上。  

注意:上面代码,主线程将先于子线程结束,所有子线程全部结束后,进程结束。

一个进程的结束,要等待内部的所有线程都结束后,才会结束。

四、线程的生命周期

1、用线程类创建一个对象时,可以说我们已经创建一个线程了,被创建的线程对象

调用start成员函数后,线程开始运行,运行的是run成员函数体,该线程参与操作

系统的调度,操作系统给每一个线程一定的时间片时间去执行,时间片到了当前线程

停止运行,其他线程运行它的时间片,如此调度,所以从单核cpu的角度看,微观看,线程

是顺序执行,由操作系统切换每个线程的执行。线程的非正常死亡之一是因terminate()

成员函数导致,所以terminate成员函数不推荐使用,因为不会考虑数据的完整性,

会暴力的杀死线程,可能会导致资源没有被释放,数据不完整等,所以在工程中

禁止调用。

2、不调用terminate()成员函数去结束一个线程,那如何优雅的结束一个线程的生命期呢?

(1)解决方案思路:

run()函数执行结束是优雅终止线程的唯一方式,因为是线程的自然死亡,run成员函数被执行完了

run成员函数被正常的返回了,这种叫做正常的死亡,所以在线程类中增加一个标志变量m_toStop(volatile bool),通过m_toStop的值判断是否需要从run()函数返回。run函数返回,为优雅

的结束线程 。volatile关键字必须去修饰这个标志变量,不需要编译去优化,而是我们每次都会去内存中去取这个值,值是易变的,所以加volatile。

3、代码如下

class MyThread :public QThread
{
protected:
    volatile bool m_toStop;
    void run();
    
public:
    MyThread()
    {
        m_toStop = false;
    }
    void stop()
    {
        m_toStop = true;
    }
};

void MyThread::run()
{
    while (!m_toStop)
    {

    }
}

上面的代码,如果run函数中的while循环中,判断到了m_toStop变量值为true了,

则会不执行while循环,跳出while循环,向下执行后,run函数就会自己返回,这个

方法是工程中,结束一个线程执行的一个很好的方法,标准优雅的去结束一个线程。

class MyThread :public QThread
{
protected:
    volatile bool m_toStop;
    void run()
    {
        int *p = new int[10000];    //申请了10000*int大小的堆空间让p指向
        for ( int i = 0; !m_toStop && (i < 10); i++ )
        {
            p[i]  = i * i;    
            sleep(1);
        }
        
        delete[] p;
    }   
    
public:
    MyThread()
    {
        m_toStop = false;
    }
    void stop()
    {
        m_toStop = true;
    }
};

int main(void)

{

    MyThread t;

    t.start();

    Sleep(5000);

    t.stop();  //优雅的结束线程

}


新闻标题:(73课)Qt中的多线程编程(一)
当前URL:http://chengdu.cdxwcx.cn/article/poiggp.html