Qt多线程同步

目录

一、多线程的本质

二、常规问题解决方案

1、串行执行及执行时间

2、并发执行及执行时间

3、结果分析

三、同步的概念与解决方法

四、完整示例代码


一、多线程的本质

并发性是多线程编程的本质。何为并发性?指在同一计算机中,存在多个计算任务,这些计算任务具有同时执行的特性,这样能提高系统性能,程序响应速度更快。

1、在宏观上,所有线程并行执行;

2、多个线程相互独立,互不干涉,那事实真是这样吗?

二、常规问题解决方案

在平常的问题解决方案中,往往都是将同一个问题分解成若干个任务去解决,这些任务在执行解决上,又可以分为串行执行和并发执行,两者在效率上是很大不同,并发性效率可能是串行的几倍。下面以0+1+2+3+ ... + 1000求和为例,可以将这个求和分为三部分:任务1为0~300,、任务2为301~600和任务3为601~1000来解决这个问题。

1、串行执行及执行时间

#include <QCoreApplication>
#include <QThread>
#include <QTime>
#include <QDebug>

class SyncThread : public QThread
{
    int m_begin_data;
    int m_end_data;
    int m_result;

public:
    SyncThread(int begin, int end)
    {
        m_begin_data = begin;
        m_end_data = end;
        m_result = 0;
    }

    int getResult()
    {
        return m_result;
    }

    void work()
    {
        this->run();
    }

protected:
    void run()
    {
        qDebug() << objectName() << "run() begin...";

        for( int i=m_begin_data; i<=m_end_data; i++ )
        {
            m_result += i;
            msleep(10);
        }

        qDebug() << objectName() << "run() end...";
    }
};

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    QTime timer;
    timer.start();
    qDebug() << "main begin...";

    SyncThread s1(0, 300);
    SyncThread s2(301, 600);
    SyncThread s3(601, 1000);

    s1.setObjectName("s1");
    s2.setObjectName("s2");
    s3.setObjectName("s3");

    s1.work();
    s2.work();
    s3.work();

    int result = s1.getResult() + s2.getResult() + s3.getResult();
    qDebug() << "result: " << result;

    qDebug() << "main end...";
    qDebug() << timer.elapsed() << " ms";
    return a.exec();
}

2、并发执行及执行时间

    //s1.work();
    //s2.work();
    //s3.work();
    
    // 在串行代码上只需要调用相应的线程启动函数即可
    s1.start();
    s2.start();
    s3.start();

3、结果分析

(1)现象:在计算耗时上,确实是缩短了好几倍,效率也提高上了,但是计算结果却是不准确的;

(2)原因:多线程间并不是完全独立毫无依赖的,在某些特殊情况下,多线程执行在时序上存在依赖。在main函数中,相继调用了三个线程去处理各自任务,但是三个线程并没有完全执行完整,计算结果就出乎我们意料了,这就是同步问题。

三、同步的概念与解决方法

1、同步的概念:在特殊情况下,控制多线程间的相对执行顺序

2、解决方法:QThread类直接提供了相关函数接口解决该问题,就是wait()方法,wait()停止当前线程的执行,等待目标线程的执行结束。

3、使用方法

    // 在串行代码上只需要调用相应的线程启动函数即可
    s1.start();
    s2.start();
    s3.start();

    s1.wait();
    s2.wait();
    s3.wait();

最后结果显示,多线程的并发性优于串行性,准确性也无误。

四、完整示例代码

#include <QCoreApplication>
#include <QThread>
#include <QTime>
#include <QDebug>

class SyncThread : public QThread
{
    int m_begin_data;
    int m_end_data;
    int m_result;

public:
    SyncThread(int begin, int end)
    {
        m_begin_data = begin;
        m_end_data = end;
        m_result = 0;
    }

    int getResult()
    {
        return m_result;
    }

    void work()
    {
        this->run();
    }

protected:
    void run()
    {
        qDebug() << objectName() << "run() begin...";

        for( int i=m_begin_data; i<=m_end_data; i++ )
        {
            m_result += i;
            msleep(10);
        }

        qDebug() << objectName() << "run() end...";
    }
};

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    QTime timer;
    timer.start();
    qDebug() << "main begin...";

    SyncThread s1(0, 300);
    SyncThread s2(301, 600);
    SyncThread s3(601, 1000);

    s1.setObjectName("s1");
    s2.setObjectName("s2");
    s3.setObjectName("s3");

//    s1.work();
//    s2.work();
//    s3.work();

    // 在串行代码上只需要调用相应的线程启动函数即可
    s1.start();
    s2.start();
    s3.start();

    s1.wait();
    s2.wait();
    s3.wait();

    int result = s1.getResult() + s2.getResult() + s3.getResult();
    qDebug() << "result: " << result;

    qDebug() << "main end...";
    qDebug() << "计算耗时: " << timer.elapsed() << " ms";
    return a.exec();
}

 

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值