加入收藏 | 设为首页 | 会员中心 | 我要投稿 我爱制作网_池州站长网 (https://www.0566zz.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 站长学院 > PHP教程 > 正文

一、多线程与临界资源的依赖

发布时间:2022-09-19 14:32:34 所属栏目:PHP教程 来源:
导读:  Qt多线程互斥「建议收藏」一、多线程与临界资源的依赖除了上一节所说的,多线程在代码执行的时序上会有依赖,那么其他地方是否还有所依赖呢?答案是有的,也就是与临界资源的问题,所谓临界资源是指每次只允许一
  Qt多线程互斥「建议收藏」一、多线程与临界资源的依赖除了上一节所说的,多线程在代码执行的时序上会有依赖,那么其他地方是否还有所依赖呢?答案是有的,也就是与临界资源的问题,所谓临界资源是指每次只允许一个线程进行访问(读或写)资源。假设两个线程都要访问一个全局变量的临界资源,两个线程谁都不让谁,进行对资源的抢占,发生了竞争,致使读写数据会出现错误,严重的可能还会导致程序运行崩溃,出错的现象谁也说不准,比如以下代码的示例:#include#include
 
  大家好,我是架构君,一个会写代码吟诗的架构师。今天说一说Qt多线程互斥「建议收藏」,希望能够帮助大家进步!!!
 
  目录
 
  一、多线程与临界资源的依赖
 
  除了上一节所说的,多线程在代码执行的时序上会有依赖,那么其他地方是否还有所依赖呢?答案是有的,也就是与临界资源的问题,所谓临界资源是指每次只允许一个线程进行访问(读或写)的资源。
 
  假设两个线程都要访问一个全局变量的临界资源,两个线程谁都不让谁,进行对资源的抢占,发生了竞争,致使读写数据会出现错误,严重的可能还会导致程序运行崩溃,出错的现象谁也说不准,比如以下代码的示例:
 
  #include
  #include
  #include
  int g_i_current_data = 0;
  class ThreadMutexA : public QThread
  {
  protected:
      void run()
      {
          qDebug() << objectName() << ": run begin...";
          while( true )
          {
              g_i_current_data++;
              qDebug() << objectName() << ": " << g_i_current_data;
              msleep(1);
          }
          qDebug() << objectName() << ": run end...";
      }
  };
  class ThreadMutexB : public QThread
  {
  protected:
      void run()
      {
          qDebug() << objectName() << ": run begin...";
          while( true )
          {
              g_i_current_data--;
              qDebug() << objectName() << ": " << g_i_current_data;
              msleep(1);
          }
          qDebug() << objectName() << ": run end...";
      }
  };
  int main(int argc, char *argv[])
  {
      QCoreApplication a(argc, argv);
      qDebug() << "main begin...";
      ThreadMutexA thread_a;
      ThreadMutexB thread_b;
      thread_a.setObjectName("ThreadMutexA");
      thread_b.setObjectName("ThreadMutexB");
      thread_a.start();
      thread_b.start();
      qDebug() << "main end...";
      return a.exec();
  }
  只听到从架构师办公室传来架构君的声音:
 
  泛泛滇滇从高斿,殷勤此路胪所求。有谁来对上联或下联?
 
  现象分析
 
  1、现象:这段小示例代码已经经过半小时的测试,幸运的是并没有出现程序崩溃,但是仔细一看,数据的打印是有问题的php多线程,我们想让这个全局变量在A线程中加1,在B线程中减1,这明显与我们想法相违背;
 
  2、原因分析:导致这现象的原因是多线程对临界资源的抢占,造成了互斥(竞争)的问题。
 
  二、互斥和解决方法
 
  1、多线程互斥:多线程在同一个时刻都需要访问(读/写)临界资源;
 
  2、解决方案:QMutex类是线程锁类,它可以保证线程间的互斥,利用线程锁可以保证临界资源的安全性。
 
  三、QMutex的主要成员函数和使用
 
  1、void QMutex::lock():(1)当锁空闲时,线程获取锁并继续执行;(2)当锁被获取时,阻塞并等待锁的释放。
 
  2、void QMutex::unlock():释放锁,同一把锁的获取lock()和释放unlock()必须成对出现
 
  3、使用
 
  此代码由Java架构师必看网-架构君整理
      QMutex mutex;
      mutex.lock();
      // do something you want
      mutex.unlock();

  四、示例代码
 
  将线程锁的概念引入上面的问题当中,并解决问题。
 
  #include
  #include
  #include
  #include
  int g_i_current_data = 0;
  QMutex g_mutex;
  class ThreadMutexA : public QThread
  {
  protected:
      void run()
      {
          qDebug() << objectName() << ": run begin...";
          while( true )
          {
              g_mutex.lock();
              g_i_current_data++;
              qDebug() << objectName() << ": " << g_i_current_data;
              g_mutex.unlock();
              msleep(1);
          }
          qDebug() << objectName() << ": run end...";
      }
  };
  class ThreadMutexB : public QThread
  {
  protected:
      void run()
      {
          qDebug() << objectName() << ": run begin...";
          while( true )
          {
              g_mutex.lock();
              g_i_current_data--;
              qDebug() << objectName() << ": " << g_i_current_data;
              g_mutex.unlock();
              msleep(1);
          }
          qDebug() << objectName() << ": run end...";
      }
  };
  int main(int argc, char *argv[])
  {
      QCoreApplication a(argc, argv);
      qDebug() << "main begin...";
      ThreadMutexA thread_a;
      ThreadMutexB thread_b;
      thread_a.setObjectName("ThreadMutexA");
      thread_b.setObjectName("ThreadMutexB");
      thread_a.start();
      thread_b.start();
      qDebug() << "main end...";
      return a.exec();
  }
 
  五、小结
 
  1、临界资源每次只允许一个线程进行访问(读/写)操作;
 
  2、QMutex线程锁可以保护线程间互斥;
 
  3、线程只有获取锁成功才能去访问临界资源;
 
  4、锁被其他线程获取时,就必须阻塞并等待锁的释放;
 
  5、线程锁的获取和释放必须在同一个线程中成对出现,类似new和delete一样。
 

(编辑:我爱制作网_池州站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!