目錄
1--創建并等待多個線程
2--數據共享
2-1--數據只讀
2-2--數據讀寫
2-3--共享數據保護簡單案例
1--創建并等待多個線程
????????創建多個線程時,可以使用同一個線程入口函數;
? ? ? ? 多個線程的執行順序與操作系統的調度機制有關,并不和創建線程的先后順序相同;
? ? ? ? 一般會將多個線程對象存放在容器中,方便進行管理;
#include <iostream>
#include <thread>
#include <vector>// 線程入口函數
void myprint(int i){std::cout << "This is thread " << i << std::endl;
}int main(int argc, char *argv[]){std::vector<std::thread> V;// 創建5個線程for(int i = 0; i < 5; i++){V.push_back(std::thread(myprint, i));}// 等待5個線程for(auto iter = V.begin(); iter != V.end(); iter++){iter->join();}// 繼續執行主線程std::cout << "This is main thread." << std::endl;return 0;
}
2--數據共享
2-1--數據只讀
#include <iostream>
#include <thread>
#include <vector>// 共享只讀數據
const std::vector<int> read_data = {1, 2, 3};// 線程入口函數
void myprint(int i){// 只讀數據std::cout << "thread " << i << " read data: " << read_data[0] << ","<< read_data[1] << "," << read_data[2] << std::endl;
}int main(int argc, char *argv[]){std::vector<std::thread> V;// 創建5個線程for(int i = 0; i < 5; i++){V.push_back(std::thread(myprint, i));}// 等待5個線程for(auto iter = V.begin(); iter != V.end(); iter++){iter->join();}// 繼續執行主線程std::cout << "This is main thread." << std::endl;return 0;
}
2-2--數據讀寫
????????不同線程對共享數據進行讀寫時,可能會發生沖突,因此需要進行特殊的處理(例如加鎖,線程間需互斥等);
2-3--共享數據保護簡單案例
????????當兩個線程對共享數據進行讀寫時,會發生沖突,可以通過互斥量(mutex)來對共享數據進行加鎖(lock)、解鎖(unlock)等操作;
? ? ? ? lock() 與 unlock() 必須成對匹配,即調用次數相同;
? ? ? ? 必須使用同一個互斥量進行加鎖和解鎖;
? ? ? ? 需要選擇正確的臨界區進行上鎖和解鎖,即保護區域需正確;
#include <iostream>
#include <thread>
#include <list>
#include <mutex> // 引入互斥class myClass{
public:// 收集數據到消息隊列void inMsgRecvQueue(){for(int i = 0; i < 100; i++){// 模擬收集消息std::cout << "Running inMsgRecvQueue(), insert one value: " << i << std::endl; // 選擇正確的臨界區進行加鎖和解鎖my_mutex.lock();msgRecvqueue.push_back(i); // 消息隊列存儲消息my_mutex.unlock();}}// 從消息隊列取數據void outMsgRecvQueue(){for(int i = 0; i < 100; i++){if(!msgRecvqueue.empty()){// 選擇正確的臨界區并使用同一個互斥量進行加鎖和解鎖my_mutex.lock(); // 加鎖// 取出數據int command = msgRecvqueue.front();msgRecvqueue.pop_front(); my_mutex.unlock(); // 解鎖}else{std::cout << "Running outMsgRecvQueue(), " "the msgRecvqueue is empty" << std::endl;}}}
private:std::list<int> msgRecvqueue; // 消息隊列std::mutex my_mutex; // 創建互斥量
};int main(int argc, char *argv[]){myClass sample1;// 使用成員函數創建線程std::thread myInMsgObj(&myClass::inMsgRecvQueue, &sample1); // 收集數據線程std::thread myOutMsgObj(&myClass::outMsgRecvQueue, &sample1); // 取出數據線程myInMsgObj.join();myOutMsgObj.join();return 0;
}