Qt 多线程同步之互斥锁

爱被打了一巴掌 2022-11-09 16:21 509阅读 0赞

生产者-消费者模型

1.QMutex

QMutex需要配对使用lock()和unlock()来实现代码段的保护

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3d6ejk1MzIwMDQ2Mw_size_16_color_FFFFFF_t_70

  1. #ifndef MYTHREAD_H
  2. #define MYTHREAD_H
  3. #include <QThread>
  4. #include <QQueue>
  5. #include <QMutex>
  6. #include <QDebug>
  7. static int data = 100;
  8. static QQueue<int> que;
  9. static QMutex mutex;
  10. class Producer : public QThread
  11. {
  12. Q_OBJECT
  13. public:
  14. explicit Producer(QThread *parent)
  15. :QThread(parent)
  16. {
  17. }
  18. protected:
  19. void run()
  20. {
  21. for(int i=0;i<data;i++) //生产者生产的快
  22. {
  23. mutex.lock();
  24. que.enqueue(i);
  25. qDebug()<<"Producer produce: "<<QString::number(i);
  26. mutex.unlock();
  27. msleep(100);
  28. }
  29. }
  30. };
  31. class Customer : public QThread
  32. {
  33. Q_OBJECT
  34. public:
  35. explicit Customer(QThread *parent,int id)
  36. :QThread(parent)
  37. ,m_id(id)
  38. {
  39. }
  40. protected:
  41. void run()
  42. {
  43. while(true)
  44. {
  45. mutex.lock();
  46. if(!que.isEmpty())
  47. {
  48. int num = que.dequeue();
  49. qDebug()<<"Customer"<<QString::number(m_id)<<" consume:"<<QString::number(num);
  50. }
  51. mutex.unlock();
  52. msleep(300);//生产者消费的慢
  53. }
  54. }
  55. private:
  56. int m_id = 0;
  57. };
  58. #endif // MYTHREAD_H

建立3个消费者和一个生产者

  1. #include <QCoreApplication>
  2. #include "MyThread.h"
  3. int main(int argc, char *argv[])
  4. {
  5. QCoreApplication a(argc, argv);
  6. Producer producer(nullptr);
  7. Customer customer1(nullptr,1);
  8. Customer customer2(nullptr,2);
  9. Customer customer3(nullptr,3);
  10. producer.start();
  11. customer1.start();
  12. customer2.start();
  13. customer3.start();
  14. return a.exec();
  15. }

2.使用QMutexLocker

QMutexLocker是另外一个简化了互斥量处理的类。QMutexLocker构造函数接受一个互斥量作为参数并将其锁定,QMutexLocker的析构函数则将此互斥量解锁,所以在QMutexLocker实例变量的生存期内的代码段得到保护,自动进行互斥量的锁定和解锁。

  1. #ifndef MYTHREAD_H
  2. #define MYTHREAD_H
  3. #include <QThread>
  4. #include <QQueue>
  5. #include <QMutex>
  6. #include <QMutexLocker>
  7. #include <QDebug>
  8. static int data = 100;
  9. static QQueue<int> que;
  10. static QMutex mutex;
  11. class Producer : public QThread
  12. {
  13. Q_OBJECT
  14. public:
  15. explicit Producer(QThread *parent)
  16. :QThread(parent)
  17. {
  18. }
  19. protected:
  20. void run()
  21. {
  22. for(int i=0;i<data;i++) //生产者生产的快
  23. {
  24. {
  25. QMutexLocker locker(&mutex);
  26. que.enqueue(i);
  27. qDebug()<<"Producer produce: "<<QString::number(i);
  28. }
  29. msleep(100);
  30. }
  31. }
  32. };
  33. class Customer : public QThread
  34. {
  35. Q_OBJECT
  36. public:
  37. explicit Customer(QThread *parent,int id)
  38. :QThread(parent)
  39. ,m_id(id)
  40. {
  41. }
  42. protected:
  43. void run()
  44. {
  45. while(true)
  46. {
  47. {
  48. QMutexLocker locker(&mutex);
  49. if(!que.isEmpty())
  50. {
  51. int num = que.dequeue();
  52. qDebug()<<"Customer"<<QString::number(m_id)<<" consume:"<<QString::number(num);
  53. }
  54. }
  55. msleep(300);//生产者消费的慢
  56. }
  57. }
  58. private:
  59. int m_id = 0;
  60. };
  61. #endif // MYTHREAD_H

发表评论

表情:
评论列表 (有 0 条评论,509人围观)

还没有评论,来说两句吧...

相关阅读

    相关 Qt 线同步读写

    1.QReadWriteLock 使用互斥量时存在一个问题:每次只能有一个线程获得互斥量的权限。如果在一个程序中有多个线程读取某个变量,使用互斥量时也必须排队。而实际上若

    相关 linux线互斥

    基本概念: 互斥变量是用pthread\_mutex\_t数据类型表示的。在使用互斥变量以前,必须首先对它进行初始化,可以把它设置为常量PTHREAD\_MUTEX

    相关 linux线同步互斥

    互斥锁(互斥量)是线程用来同步彼此行为的工具。互斥锁可以帮助线程同步对共享资源的使用,以防如下情况发生:线程某甲试图访问一共享变量时,线程某乙正在对其修改。 未避免线程更新共