多线程间的互斥(上)
多线程 互斥
2023-09-14 09:12:37 时间
值得思考的问题:
多个线程除了在时序上可能产生相互依赖,在其他方面是否也可能产生相互依赖呢?
生产消费者问题:
-有n个生产者同时制造产品,并把产品存入仓库中
-有m个消费者同时需要从仓库中取出产品
-规则:
当仓库未满,任意生产者可以存入产品
当仓库未空,任意消费者可以取出产品
编程实验:生产消费者问题
#include <QCoreApplication> #include <QThread> #include <QDebug> static QString q_store; //通过全局变量来模拟唯一的仓库 class Producer : public QThread { protected: void run() { int count = 0; while(true) { //每次产生的数字在0-10之间,模拟了生产者将生产好的产品(一个数字)放入到仓库中(一个字符串类的对象) q_store.append(QString::number((count++) % 10)); qDebug() << objectName() << " :" + q_store; //用字符串中字符表示当前仓库中的商品 msleep(1); } } }; class Customer : public QThread { protected: void run() { while(true) { if(q_store != " ") { q_store.remove(0,1); //删除字符串中的第一个字符,表示取出一个商品 qDebug() << objectName() << " : " + q_store; } msleep(1); } } }; int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); qDebug() << "main begin()" ; Producer p; Customer c; p.setObjectName("Producer"); c.setObjectName("Customer"); p.start(); c.start(); qDebug() << "main end()"; return a.exec(); }
在程序中,如果只分析生产者是没有问题的,同样如果只分析消费者也是没有问题的。出现问题的原因就是生产者和消费者是并行执行的,并且共享一个仓库。两个线程之间没有任何的限制或约束。考虑一种情况,生产者在向仓库中放入产品的同时,消费者从仓库中取产品。相当于对共享资源同时读写,这肯定是不对的,也是不行的。
临界资源(Critical Resource)
-每次只允许一个线程进行访问(读/写)的资源
-线程间的互斥(竞争)
-多个线程在同一时刻都需要访问临界资源
QMutex类是一把线程锁,保证线程间的互斥
-利用线程锁能够保证临界资源的安全性
QMutex中的关键成员函数
-void lock()
当锁空闲时,获取锁并继续执行
当锁被获取,阻塞并等待锁释放
-void unlock()
释放锁(同一把锁的获取和释放必须在同一线程中成对出现)
QMutex使用示例
QMutex mutex;
mutex.lock();
//do something with critical resource
mutex.unlock();
注意:如果mutex在调用unlock()时处于空闲状态(即在调用lock函数之前就调用了unlock),那么程序的行为是未定的。所谓未定义就是什么时候产生bug,是不知道的。
解决生产者消费者问题:
#include <QCoreApplication> #include <QThread> #include <QDebug> #include <QMutex> static QString q_store; //通过全局变量来模拟唯一的仓库 static QMutex mutex; class Producer : public QThread { protected: void run() { int count = 0; while(true) { mutex.lock(); //每次产生的数字在0-10之间,模拟了生产者将生产好的产品(一个数字)放入到仓库中(一个字符串类的对象) q_store.append(QString::number((count++) % 10)); qDebug() << objectName() << " :" + q_store; //用字符串中字符表示当前仓库中的商品 msleep(1); mutex.unlock(); } } }; class Customer : public QThread { protected: void run() { while(true) { mutex.lock(); if(q_store != " ") { q_store.remove(0,1); //删除字符串中的第一个字符,表示取出一个商品 qDebug() << objectName() << " : " + q_store; } msleep(1); mutex.unlock(); } } }; int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); qDebug() << "main begin()" ; Producer p; Customer c; p.setObjectName("Producer"); c.setObjectName("Customer"); p.start(); c.start(); qDebug() << "main end()"; return a.exec(); }
相关文章
- 5天不再惧怕多线程——第三天 互斥体
- (单例设计模式中)懒汉式与饿汉式在多线程中的不同
- 多线程下载(转)
- C++ 多线程(两个线程卖火车票)
- java核心知识点学习----多线程间的数据共享的几种实现方式比较
- golang与python多线程的并发速度
- object-c 多线程 加锁
- 多线程避免使用SimpleDateFormat及替代方案
- 请解释一下Java多线程回调是什么意思?
- 解决多线程安全问题-无非两个方法synchronized和lock 具体原理以及如何 获取锁AQS算法 (百度-美团)
- Qt多线程:使用互斥锁
- java多线程之ThreadLoal详解
- Python 多线程进程高级指南(二)
- C++多线程编程:同步之互斥量Mutex
- 【动画详解原理系列】2.多线程并发编程与锁
- 001-多线程-JUC线程池-线程池架构-Executor、ExecutorService、ThreadPoolExecutor、Executors
- 14.1 threading--多线程
- Python中多线程的阻塞问题
- C# 多线程与线程扫描器
- Java核心类库之(多线程:实现多线程、线程同步)