Qt——多线程间的互斥

1.示例:消费者和生产者问题

消费者消费一个产品,生产者生产一个产品

复制代码
#include <QCoreApplication>
#include <QThread>
#include <QDebug>
#include <QString>

static QString g_store;

class Producer : public QThread
{
protected:
    void run()
    {
        int count = 0;
        while(true)
        {
            g_store.append(QString::number((count++) % 10));

            qDebug() << objectName() << ":" + g_store;

            msleep(1);
        }
    }
};

class Customer : public QThread
{
protected:
    void run()
    {
        while(true)
        {
            if( g_store != "")
            {
                g_store.remove(0, 1); //去除第一个元素
                qDebug() << objectName() << ":" + g_store;
            }
            msleep(1);
        }

    }
};

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    Producer p;
    Customer c;

    p.setObjectName("Producer");
    c.setObjectName("Customer");

    p.start();
    c.start();

    return QCoreApplication::exec();
}

但是当消费者和生产者同时访问g_store时,就会产生竞争,程序会崩溃

2.临界资源:每次只允许一个线程进行访问(读/写)的资源

线程间的互斥(竞争):多个线程在同一时刻都需要访问临界资源

QMutex类是一把线程锁,保证线程间的互斥,利用线程锁能够保证临界资源的安全性

3.QMutex中的关键成员函数

  • void lock() 当锁空闲时,获取锁并继续执行;当锁被获取,阻塞并等待锁释放

  • void unlock() 释放锁(同一把锁的获取和释放锁必须在同一线程中成对出现)

    #include
    #include
    #include
    #include
    #include

    static QString g_store;
    static QMutex g_mutex;

    class Producer : public QThread
    {
    protected:
    void run()
    {
    int count = 0;
    while(true)
    {
    g_mutex.lock();
    g_store.append(QString::number((count++) % 10));

    复制代码
              qDebug() << objectName() << ":" + g_store;
              
              g_mutex.unlock();
              msleep(1);
          }
      }

    };

    class Customer : public QThread
    {
    protected:
    void run()
    {
    while(true)
    {
    g_mutex.lock();
    if( g_store != "")
    {
    g_store.remove(0, 1); //去除第一个元素
    qDebug() << objectName() << ":" + g_store;
    }
    g_mutex.unlock();
    msleep(1);
    }

    复制代码
      }

    };

    int main(int argc, char *argv[])
    {
    QCoreApplication a(argc, argv);

    复制代码
      Producer p;
      Customer c;
    
      p.setObjectName("Producer");
      c.setObjectName("Customer");
    
      p.start();
      c.start();
    
      return QCoreApplication::exec();

    }

相关推荐
霸道流氓气质8 分钟前
Saga模式入门与实战:编排与协同模式、补偿设计原则与Java生产级实现
java·开发语言
Lhan.zzZ13 分钟前
Linux + Qt/QML:解决 QtQuick.VirtualKeyboard.Plugins 模块加载失败与环境变量配置
linux·数据库·qt
silvamux_30 分钟前
OpenAI Python SDK v1 迁移实战
开发语言·python
旋生万物31 分钟前
螺旋数不是玄学:Python 实现广义复数与等角螺线
开发语言·人工智能·python·云原生·aigc·软件工程·后端开发
半杯咖啡半行码32 分钟前
Linux字符设备驱动实战:ioctl接口与GPIO操作指南
linux·开发语言
ZoeLandia33 分钟前
TypeScript 07:工程化——import type、声明文件与 tsconfig
开发语言·前端·typescript
小小程序猴142 分钟前
用工程视角建模企业AI培训周期:三段账本估算器(Python实现)
开发语言·人工智能·python
开开心心_Every1 小时前
文件查重软件批量删除重复文件释放空间
java·开发语言·c#·计算机外设·ocr·excel·perl
认真的小羽❅1 小时前
ThreadLocal 在虚拟线程间要小心
java·开发语言·jvm
普通人61 小时前
宝塔中实现按地区过滤和官网跳转伪静态
服务器·开发语言·nginx·1024程序员节