C++多线程编程之多线程数据共享问题

 通过容器创建多个线程

红塔网站制作公司哪家好,找成都创新互联!从网页设计、网站建设、微信开发、APP开发、成都响应式网站建设公司等网站项目制作,到程序开发,运营维护。成都创新互联从2013年开始到现在10年的时间,我们拥有了丰富的建站经验和运维经验,来保证我们的工作的顺利进行。专注于网站建设就选成都创新互联。

 
 
 
  1. #include  
  2. #include  
  3. #include  
  4. void printTest(int num)  
  5. { 
  6.     std::cout << "子线程:" << num << "启动" << std::endl; 
  7.     std::cout << "子线程:" << num << "结束" << std::endl; 
  8. } 
  9. int main()  
  10. { 
  11.     std::vector test; 
  12.     for (int i = 0; i < 10; i++)  
  13.     { 
  14.         test.push_back(new std::thread(printTest, i)); 
  15.     } 
  16.     for (auto& pmove : test) 
  17.     { 
  18.         pmove->join(); 
  19.     } 
  20.     std::cout << "主线程" << std::endl; 
  21.     return 0; 
  22. } 

 数据共享问题分析只读数据:稳定安全,不需要特殊处理,直接读即可

 
 
 
  1. #include  
  2. #include  
  3. #include  
  4. std::vector g_data={ 1,2,3 }; 
  5. void printTest(int num)  
  6. { 
  7.  std::cout << "子线程:" << num << "读操作" << std::endl; 
  8.  for (auto pmove : g_data)  
  9.  { 
  10.  std::cout << pmove << std::endl; 
  11.  } 
  12. } 
  13. int main()  
  14. { 
  15.  std::vector test; 
  16.  for (int i = 0; i < 10; i++)  
  17.  { 
  18.  test.push_back(new std::thread(printTest, i)); 
  19.  } 
  20.  for (auto& pmove : test) 
  21.  { 
  22.  pmove->join(); 
  23.  } 
  24.  std::cout << "主线程" << std::endl; 
  25.  return 0; 
  26. } 

 有读有写:需要做特别处理(写只做写,读只做读操作,保持共享数据只有唯一操作),不然会引发崩溃

 
 
 
  1. #include  
  2. #include  
  3. #include  
  4. class SeaKing  
  5. { 
  6. public: 
  7.  void makeFriend() 
  8.  { 
  9.  for (int i = 0; i < 100000; i++)  
  10.  { 
  11.  std::cout << "增加一个" << std::endl; 
  12.  mm.push_back(i); 
  13.  } 
  14.  } 
  15.  void breakUp()  
  16.  { 
  17.  for (int i = 0; i < 100000; i++)  
  18.  { 
  19.  if (!mm.empty())  
  20.  { 
  21.  std::cout << "减少一个:"<
  22.  mm.pop_front(); 
  23.  } 
  24.  else  
  25.  { 
  26.  std::cout << "已空" << std::endl; 
  27.  } 
  28.  } 
  29.  } 
  30. protected: 
  31.  std::list mm; 
  32. }; 
  33. int main()  
  34. { 
  35.  SeaKing man; 
  36.  std::thread t1(&SeaKing::makeFriend, &man); 
  37.  std::thread t2(&SeaKing::breakUp, &man); 
  38.  t1.join(); 
  39.  t2.join(); 
  40.  return 0; 
  41. } 
  42. //以上程序会异常退出 

 加锁的方式解决数据共享问题互斥量mutex: 互斥量可以理解为锁,他是一个mutex类的对象通过调用成员函数lock函数进行加锁通过调用成员函数unlock函数进行解锁

 
 
 
  1. #include  
  2. #include  
  3. #include  
  4. #include  //1.包含头文件 
  5. class SeaKing  
  6. { 
  7. public: 
  8.  void makeFriend() 
  9.  { 
  10.  for (int i = 0; i < 100000; i++)  
  11.  { 
  12.  m_mutex.lock(); 
  13.  std::cout << "增加一个" << std::endl; 
  14.  mm.push_back(i); 
  15.  m_mutex.unlock(); 
  16.  } 
  17.  } 
  18.  bool readInfo()  
  19.  { 
  20.  m_mutex.lock(); //2.加锁 
  21.  if (!mm.empty()) 
  22.  { 
  23.  std::cout << "减少一个:" << mm.front() << std::endl; 
  24.  mm.pop_front(); 
  25.  m_mutex.unlock(); 
  26.  return true; 
  27.  } 
  28.  m_mutex.unlock(); 
  29.  return false; 
  30.  } 
  31.  void breakUp()  
  32.  { 
  33.  for (int i = 0; i < 100000; i++) 
  34.  { 
  35.  int result = readInfo(); 
  36.  if (result == false)  
  37.  { 
  38.  std::cout << "已空" << std::endl; 
  39.  } 
  40.  } 
  41.  } 
  42. protected: 
  43.  std::list mm; 
  44.  std::mutex m_mutex; //创建互斥量对象 
  45. }; 
  46. int main()  
  47. { 
  48.  SeaKing man; 
  49.  std::thread t1(&SeaKing::makeFriend, &man); 
  50.  std::thread t2(&SeaKing::breakUp, &man); 
  51.  t1.join(); 
  52.  t2.join(); 
  53.  return 0; 
  54. } 

 注意:lock函数与unlock都是成对出现,如果lock了没有调用unlock会引发异常,abort终止程序通过lock_guard加锁。

 
 
 
  1. #include  
  2. #include  
  3. #include  
  4. #include  
  5. class SeaKing  
  6. { 
  7. public: 
  8.     void makeFriend() 
  9.     { 
  10.         std::lock_guard sbguard(m_mutex); 
  11.         for (int i = 0; i < 100000; i++)  
  12.         { 
  13.             std::cout << "增加一个" << std::endl; 
  14.             mm.push_back(i); 
  15.         } 
  16.     } 
  17.     bool readInfo()  
  18.     { 
  19.         std::lock_guard sbguard(m_mutex); 
  20.         if (!mm.empty()) 
  21.         { 
  22.             std::cout << "减少一个:" << mm.front() << std::endl; 
  23.             mm.pop_front(); 
  24.             return true; 
  25.         } 
  26.         return false; 
  27.     } 
  28.     void breakUp()  
  29.     { 
  30.         for (int i = 0; i < 100000; i++) 
  31.         { 
  32.             int result = readInfo(); 
  33.             if (result == false)  
  34.             { 
  35.                 std::cout << "已空" << std::endl; 
  36.             } 
  37.         } 
  38.     } 
  39. protected: 
  40.     std::list mm; 
  41.     std::mutex m_mutex; 
  42. }; 
  43. int main()  
  44. { 
  45.     SeaKing man; 
  46.     std::thread t1(&SeaKing::makeFriend, &man); 
  47.     std::thread t2(&SeaKing::breakUp, &man); 
  48.     t1.join(); 
  49.     t2.join(); 
  50.     return 0; 
  51. } 

 其实lock_guard 在构造函数中进行lock,在析构函数中进行unlock,本质上还是lock与unlock操作。


当前题目:C++多线程编程之多线程数据共享问题
当前路径:http://www.jxruijie.cn/article/dphjgps.html