C++多線程編程之多線程數據共享問題
作者:C語言基礎
本篇給大家詳細介紹C++多線程編程之多線程數據共享問題,希望能夠幫助到你!
通過容器創建多個線程
- #include <vector>
- #include <iostream>
- #include <thread>
- void printTest(int num)
- {
- std::cout << "子線程:" << num << "啟動" << std::endl;
- std::cout << "子線程:" << num << "結束" << std::endl;
- }
- int main()
- {
- std::vector<std::thread* > test;
- for (int i = 0; i < 10; i++)
- {
- test.push_back(new std::thread(printTest, i));
- }
- for (auto& pmove : test)
- {
- pmove->join();
- }
- std::cout << "主線程" << std::endl;
- return 0;
- }
數據共享問題分析只讀數據:穩定安全,不需要特殊處理,直接讀即可
- #include <vector>
- #include <iostream>
- #include <thread>
- std::vector<int> g_data={ 1,2,3 };
- void printTest(int num)
- {
- std::cout << "子線程:" << num << "讀操作" << std::endl;
- for (auto pmove : g_data)
- {
- std::cout << pmove << std::endl;
- }
- }
- int main()
- {
- std::vector<std::thread* > test;
- for (int i = 0; i < 10; i++)
- {
- test.push_back(new std::thread(printTest, i));
- }
- for (auto& pmove : test)
- {
- pmove->join();
- }
- std::cout << "主線程" << std::endl;
- return 0;
- }
有讀有寫:需要做特別處理(寫只做寫,讀只做讀操作,保持共享數據只有唯一操作),不然會引發崩潰
- #include <list>
- #include <iostream>
- #include <thread>
- class SeaKing
- {
- public:
- void makeFriend()
- {
- for (int i = 0; i < 100000; i++)
- {
- std::cout << "增加一個" << std::endl;
- mm.push_back(i);
- }
- }
- void breakUp()
- {
- for (int i = 0; i < 100000; i++)
- {
- if (!mm.empty())
- {
- std::cout << "減少一個:"<<mm.front() << std::endl;
- mm.pop_front();
- }
- else
- {
- std::cout << "已空" << std::endl;
- }
- }
- }
- protected:
- std::list<int> mm;
- };
- int main()
- {
- SeaKing man;
- std::thread t1(&SeaKing::makeFriend, &man);
- std::thread t2(&SeaKing::breakUp, &man);
- t1.join();
- t2.join();
- return 0;
- }
- //以上程序會異常退出
加鎖的方式解決數據共享問題互斥量mutex: 互斥量可以理解為鎖,他是一個mutex類的對象通過調用成員函數lock函數進行加鎖通過調用成員函數unlock函數進行解鎖
- #include <list>
- #include <iostream>
- #include <thread>
- #include <mutex> //1.包含頭文件
- class SeaKing
- {
- public:
- void makeFriend()
- {
- for (int i = 0; i < 100000; i++)
- {
- m_mutex.lock();
- std::cout << "增加一個" << std::endl;
- mm.push_back(i);
- m_mutex.unlock();
- }
- }
- bool readInfo()
- {
- m_mutex.lock(); //2.加鎖
- if (!mm.empty())
- {
- std::cout << "減少一個:" << mm.front() << std::endl;
- mm.pop_front();
- m_mutex.unlock();
- return true;
- }
- m_mutex.unlock();
- return false;
- }
- void breakUp()
- {
- for (int i = 0; i < 100000; i++)
- {
- int result = readInfo();
- if (result == false)
- {
- std::cout << "已空" << std::endl;
- }
- }
- }
- protected:
- std::list<int> mm;
- std::mutex m_mutex; //創建互斥量對象
- };
- int main()
- {
- SeaKing man;
- std::thread t1(&SeaKing::makeFriend, &man);
- std::thread t2(&SeaKing::breakUp, &man);
- t1.join();
- t2.join();
- return 0;
- }
注意:lock函數與unlock都是成對出現,如果lock了沒有調用unlock會引發異常,abort終止程序通過lock_guard加鎖。
- #include <list>
- #include <iostream>
- #include <thread>
- #include <mutex>
- class SeaKing
- {
- public:
- void makeFriend()
- {
- std::lock_guard<std::mutex> sbguard(m_mutex);
- for (int i = 0; i < 100000; i++)
- {
- std::cout << "增加一個" << std::endl;
- mm.push_back(i);
- }
- }
- bool readInfo()
- {
- std::lock_guard<std::mutex> sbguard(m_mutex);
- if (!mm.empty())
- {
- std::cout << "減少一個:" << mm.front() << std::endl;
- mm.pop_front();
- return true;
- }
- return false;
- }
- void breakUp()
- {
- for (int i = 0; i < 100000; i++)
- {
- int result = readInfo();
- if (result == false)
- {
- std::cout << "已空" << std::endl;
- }
- }
- }
- protected:
- std::list<int> mm;
- std::mutex m_mutex;
- };
- int main()
- {
- SeaKing man;
- std::thread t1(&SeaKing::makeFriend, &man);
- std::thread t2(&SeaKing::breakUp, &man);
- t1.join();
- t2.join();
- return 0;
- }
其實lock_guard 在構造函數中進行lock,在析構函數中進行unlock,本質上還是lock與unlock操作。
責任編輯:姜華
來源:
今日頭條