C++/Qt 线程同步

一、前言


        前一篇文章提供了一个通过信号与主线程通信,实现多线程的程序,并在最初的多线程文章里提供了一篇来自Qt官方文档的多线程的示例。这篇文章主要是衔接上述两篇文章,对多线程这块内容继续补充,因为不管是C++编程,还是Qt编程,线程这块内容都是极为重要的,它能让应用程序不至于在处理大量事件时出现线程阻塞,以至于应用程序崩溃。如果上述两篇内容都没看过,可以快速点击下面的链接直达按需查阅。

        前文《多线程(续)》文章:C++/Qt 多线程(续)-CSDN博客 因为这里将会继续在提供的示例编程上加以补充,也就是将线程同步的编程加在原先的示例中,如需要,可配套查阅。

        前文《多线程》文章:C++/Qt 多线程-CSDN博客

二、线程同步


        在多线程程序中,线程之间的通信和同步是重要的问题。Qt提供了QMutex、QWaitCondition、QSemaphore等多个类用于实现线程同步。

        1、线程同步的概念

        在多线程程序中,由于存在 多个线程,线程之间可能需要访问同一个变量,或一个线程需要等待另一个线程完成某个操作后才产生相应的动作。例如前文的例子中,工作线程生成随机的骰子点数,主线程读取骰子点数并显示,,主线程需要等待工作线程生成一个新的骰子点数后再读取数据。示例中使用了信号与槽的机制,在生成新的点数之后通过信号通知主线程读取新的数据。

        如果不使用信号与槽且改变了计算变量m_diceValue的值的方法,TDiceThread的函数run()的代码变为如下内容:

void TDiceThread::run()
{
    //线程的任务
    m_stop = false;
    m_paused = true;   //启动线程后暂时不掷骰子
    m_seq = 0;
    while(!m_stop){     //循环体
        if(!m_paused){
            m_diceValue = 0;
            for(int i = 0;i<5;i++)  //对多个随机数求平均值
            m_diceValue += QRandomGenerator::global()->bounded(1,7);     //生成随机整数,范围为[1,6]
            m_diceValue = m_diceValue/5;
            m_seq++;
            //emit newValue(m_seq,m_diceValue);   //发射信号
        }
        msleep(500);
    }
    //在m_stop = true 时结束线程任务
    quit();
}

        TDiceThread类需要定义一个公有函数返回m_diceValue的值,以便在主程序中调用此函数读取骰子的点数,如:

int TDiceThread::diceValue()
{
    return m_diceThread;
}

        由于没有使用信号与槽的关联机制,主线程只能采用不断查询的方式主动查询是否有新数据,并在有新数据时读取新数据,但是在主线程调用函数diceThread()读取骰子点数时,工作线程可能正在运行run()函数中修改m_diceValue值得语句,即可能正在运行if语句中得关键代码。

        这段代码可能需要运行较长的事件,且会不断修改变量m_diceValue的值,运行这段代码时不能被主线程调用的diceValue()函数打断,因为如果被打断,函数diceValue()返回的值可能是错误的。

        因此,这段代码是需要被保护起来的,其在运行过程中不能被其它线程打断,以确保计算结果的完整性,这就涉及线程同步的问题。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

张鱼小丸子_微辣

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值