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

开发 后端
本篇给大家详细介绍C++多线程编程之多线程数据共享问题,希望能够帮助到你!

[[385369]]

 通过容器创建多个线程

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

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

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

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

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

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

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

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

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

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

 

责任编辑:姜华 来源: 今日头条
相关推荐

2021-02-25 15:58:46

C++线程编程开发技术

2023-06-13 13:39:00

多线程异步编程

2023-06-06 08:17:52

多线程编程Thread类

2023-06-05 07:56:10

线程分配处理器

2012-05-18 10:36:20

CC++编程

2010-01-18 14:09:58

C++多线程

2009-08-17 16:56:51

C#多线程控制进度条

2021-12-26 18:22:30

Java线程多线程

2009-03-12 10:52:43

Java线程多线程

2021-06-29 07:47:23

多线程协作数据

2013-07-16 10:12:14

iOS多线程多线程概念多线程入门

2013-06-07 16:30:08

iOS多线程iOS开发NSThread

2016-10-09 20:15:30

多线程多进程

2010-02-04 10:19:39

C++多线程

2010-02-05 15:30:54

C++多线程测试

2011-08-18 17:07:23

IOS开发多线程NSInvocatio

2010-01-21 11:25:44

linux多线程线程资源

2023-06-07 13:49:00

多线程编程C#

2021-12-28 09:10:55

Java线程状态

2023-06-16 08:36:25

多线程编程数据竞争
点赞
收藏

51CTO技术栈公众号