C++多線程編程二
阿新 • • 發佈:2018-08-22
hang int ftime 答案 tro 類型 情況下 根據 diff
1. 死鎖與解鎖:
#include <iostream> #include <thread> #include <mutex> using namespace std; //thread引用類型函數,模板,避免類型轉換,盡量指針,引用 //鎖住一個變量之後,盡快操作完解鎖,不要再鎖,否則互鎖 #define COUNT 100000 mutex g_mutex1, g_mutex2;//互斥量 void add1(int *p1, int *p2) { for (int i = 0; i < COUNT; i++) { /*g_mutex1.lock(); p1++; g_mutex2.lock(); p2++; g_mutex1.unlock(); g_mutex2.unlock();*/ g_mutex1.lock(); (*p1)++; g_mutex1.unlock(); g_mutex2.lock(); (*p2)++; g_mutex2.unlock(); } } void add2(int *p1, int *p2) { for (int i = 0; i < COUNT; i++) { /*g_mutex2.lock(); g_mutex1.lock(); p1++; g_mutex1.unlock(); p2++; g_mutex2.unlock();*/ g_mutex2.lock(); (*p2)++; g_mutex2.unlock(); g_mutex1.lock(); (*p1)++; g_mutex1.unlock(); } } void main() { int a = 0; int b = 0; thread th1(add1, &a, &b); thread th2(add2, &a, &b); th1.join(); th2.join();while (1) { cout << a << endl; cout << b << endl; this_thread::sleep_for(chrono::seconds(1)); } cin.get(); }
2. 迅雷面試題:
編寫一個程序,開啟3個線程,這3個線程的ID分別為A、B、C,每個線程將自己的ID在屏幕上打印10遍,
要求輸出結果必須按ABC的順序顯示。如:ABCABC...,依次遞推。
【參考答案】
//編寫一個程序,開啟3個線程,這3個線程的ID分別為A、B、C,每個線程將自己的ID在屏幕上打印10遍, //要求輸出結果必須按ABC的順序顯示。如:ABCABC...,依次遞推。 #include <iostream> #include <thread> #include <mutex> #include <condition_variable> using namespace std; int LOOP = 10; //循環次數 int flag = 0; //標識符 012012012012 mutex m; condition_variable cv; void fun(int id) { for (int i = 0; i < LOOP; i++) { unique_lock<mutex> ulk(m); //設定鎖定 while ((id-65) != flag) { cv.wait(ulk); //不是該出現的場合,就等待 } cout << (char)id; //轉換id flag = (flag + 1) % 3; //012,012,012,... cv.notify_all(); //通知全部 } } void main() { thread t1(fun, 65); thread t2(fun, 66); thread t3(fun, 67); t1.join(); t2.join(); t3.join(); cin.get(); }
運行結果:
【分析】若題目變為:4個線程,輸出結果要求為: ABCDABCDABCD...又該如何做呢?
//編寫一個程序,開啟3個線程,這3個線程的ID分別為A、B、C,每個線程將自己的ID在屏幕上打印10遍, //要求輸出結果必須按ABC的順序顯示。如:ABCABC...,依次遞推。 #include <iostream> #include <thread> #include <mutex> #include <condition_variable> using namespace std; int LOOP = 10; //循環次數 int flag = 0; //標識符 012012012012 mutex m; condition_variable cv; void fun(int id) { for (int i = 0; i < LOOP; i++) { unique_lock<mutex> ulk(m); //設定鎖定 while ((id-65) != flag) { cv.wait(ulk); //不是該出現的場合,就等待 } cout << (char)id; //轉換id flag = (flag + 1) % 4; //012,012,012,... cv.notify_all(); //通知全部 } } void main() { thread t1(fun, 65); thread t2(fun, 66); thread t3(fun, 67); thread t4(fun, 68); t1.join(); t2.join(); t3.join(); t4.join(); cin.get(); }
運行結果:
3. 思考:上題中若變為開啟5個線程,ID分別為1,2,3,4,5,每個線程將自己的ID在屏幕上打印10遍,要求輸出結果為:12345,54321,12345,54321,...依此類推。
4. 線程交換 swap:
#include <iostream> #include <thread> using namespace std; void main() { thread t1([]() {cout << "ZhangShan"<<endl; }); thread t2([]() {cout << "LiSi"<<endl; }); cout << "t1.get_id():" << t1.get_id() << " t2.get_id():" << t2.get_id() << endl; swap(t1, t2); //交換句柄 cout << "t1.get_id():" << t1.get_id() << " t2.get_id():" << t2.get_id() << endl; t1.join(); t2.join(); cin.get(); }
5. 線程移動 move:
#include <iostream> #include <thread> #include <cstdlib> using namespace std; void main() { thread t1([]() { int i = 0; while (1) { i++; if (i > 1000000000) { break; } } cout << i << endl; system("pause"); }); cout << "t1:" << t1.get_id() << endl; //6872 //t1.join(); thread t2 = move(t1);//線程移動,t2具備了t1的屬性,t1掛了 cout << "t1:" << t1.get_id() << endl; //0 cout << "t2:" << t2.get_id() << endl; //6872 t2.join(); cin.get(); }
運行結果:
6. 線程自動加解鎖:
#include <iostream> #include <thread> #include <mutex> using namespace std; #define N 10000000 mutex g_mutex;//全局互斥量 void add(int *p) { for (int i = 0; i < N; i++) { unique_lock<mutex> ulk(g_mutex); //沒有mutex所有權,自動加鎖自動解鎖,根據塊語句鎖定 //根據mutex屬性來決定,是否可以加鎖 //lock_guard<mutex> lgd(g_mutex); //擁有mutex所有權,自動加鎖自動解鎖 //讀取mutex失敗的情況下就會一直等待 (*p)++; } } void main() { int a = 0; thread t1(add, &a); thread t2(add, &a); t1.join(); t2.join(); cout << a << endl; cin.get(); }
7. 線程等待固定時間:
#include <iostream> #include <thread> #include <chrono> #include <mutex> #include <condition_variable> #include <cstdlib> #include <ctime> using namespace std; condition_variable cv; mutex m; bool done=false; void run() { auto start = chrono::high_resolution_clock::now(); //當前時間 auto end = start + chrono::seconds(3); unique_lock<mutex> ulk(m); while (!done) { if (cv.wait_until(ulk, end) == cv_status::timeout)//超時 { done = true; break; } } //this_thread::sleep_until(end); system("pause"); } void main1601() { thread th(run); cin.get(); } void main() { time_t t1, t2; auto start = chrono::high_resolution_clock::now(); //當前時間 t1 = time(&t1); double db = 0; for (int i = 0; i < 1000000000; i++) { db += i; } auto end = chrono::high_resolution_clock::now(); //當前時間 t2 = time(&t2); cout << (end - start).count() << endl; //10^-9秒(ns) cout << difftime(t2, t1) << endl; cin.get(); }
C++多線程編程二