zoukankan      html  css  js  c++  java
  • 第七十五课、多线程间的互斥(上)------------------狄泰软件学院

    一、多线程间的互斥

    1、生产消费者问题

    (1)、有n个生产者同时制造产品,并把产品放入仓库中

    (2)、有m个消费者同时从仓库中取出产品

    (3)、规则

    A、当仓库未满,任意生产者可以存入产品

    B、当仓库未空,任意消费者可以取出产品

    2、生活中的线程互斥例子

    标示牌用于指示是否可用:

    红绿灯标识十字路口是否可用:

    3、线程互斥的相关概念

    (1)、临界资源(Critical Resource):每次只允许一个线程访问(读/写)的资源

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

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

    4、QMutex中的关键成员函数(锁就是类似上面两个生活中例子的标识

    (1)、void lock()

    A、当锁空闲时,获取锁并继续执行

    B、当锁别人被获取,堵塞并等待锁释放

    (2)、void unlock()

    A、释放锁同一把锁的获取和释放必须在同一线程中成对出现

    #include <QCoreApplication>
    #include <QThread>
    #include <QMutex>
    #include <QDebug>
    
    #define MAXSTORAGE 10 //最大仓库容量
    
    static QMutex g_mutex;
    static QString g_store;
    
    //生产者
    class Producer : public QThread
    {
    protected:
        void run()
        {
            int count = 0;
    
            while(true)//保证每个一毫秒生产产品
            {
                g_mutex.lock();//若没有锁,程序运行一下可能崩溃,因为两个线程是并行的,生产者写的时候消费者来读,
                                //就会产生冲突
                if(g_store.count() <= MAXSTORAGE)
                {
                    g_store.append(QString::number((count++) % 10));//产生的数字总是在0-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.count()>0)
                {
                    g_store.remove(0, 1);
    
                    qDebug() << objectName() << ":" + g_store;
                }
    
                g_mutex.unlock();
    
                msleep(1);
            }
        }
    };
    
    int main(int argc, char *argv[])
    {
        QCoreApplication a(argc, argv);
    
        qDebug() << "main begin";
    
        Producer p;
        Customer c;
    
        p.setObjectName("Produer");
        c.setObjectName("Customer");
    
        p.start();
        c.start();
    
        qDebug() << "main end";
    
        return a.exec();
    }
    用线程锁解决生产消费者的问题

    二、小结

    (1)、临界资源每次只允许一个线程访问(读/写)

    (2)、线程锁(QMutex)用于保护临界资源

    (3)、线程只有获取锁之后才能访问临界资源

    (4)、锁被其它线程获取时,当前线程处于等待状态

    (5)、线程锁的获取和释放必须在同一线程中成对出现

  • 相关阅读:
    vue之v-on
    垂直居中下
    垂直居中上
    vue之v-for
    vue之v-if和v-show
    vue之v-model
    vue之v-bind
    数学---目录
    【数学】证明题
    【计算机网络】应用层
  • 原文地址:https://www.cnblogs.com/gui-lin/p/6443690.html
Copyright © 2011-2022 走看看