有這樣一個場景,底層須要給上層A提供一套c語言接口,共上層A的C++調用。而上層是併發的,在不一樣場景下,底層接口是不相同的,好比C與D,上層C++接口不能直接看到底層的不一樣實現,而是應該上層接口調用下層接口時,傳入一個場景id給B,有B來負責依據id來調用C仍是D。因此,因爲A支持併發,因此B不能阻塞,同時A能夠保證,C或者D只能同時被一個線程訪問,因爲不放心A,因此B本身對C與D作了加鎖操做。使用C++ STL中的線程庫實現。ios
【問題一】C++對象的析構多線程
#include<iostream> #include<thread> using namespace std; class A { public: A() { cout << "start" << endl; } ~A() { cout << "end" << endl; } }; void f(int id) { if (id == 0) { // 在這裏定義一個對象,出了{},則對象會被析構 A a; } else { A a; } cout << "f end" << endl; } int main(int argc, int * argv[]) { f(0); system("pause"); }
結果以下:架構
能夠看出,該對象的做用域爲{},該問題是爲了驗證下面的lock_guard的能正確的加鎖與解鎖。併發
【二】實現上圖A B C/D的架構函數
#include<iostream> #include<thread> #include<mutex> using namespace std; mutex mA; mutex mB; void f0() { cout << "enter f0" << endl; for (int i = 0; i <5; i++) { cout << "i=" << i << endl; } } void f1() { cout << "enter f1" << endl; for (int i = 20; i < 25; i++) { cout << "i=" << i << endl; } } void f(int id) { if (id == 0) { //分場景加鎖保護,防止f0被多線程訪問 std::lock_guard<mutex> _1(mA); f0(); } else { //分場景加鎖保護 std::lock_guard<mutex> _1(mB); f1(); } cout << "f end" << endl; } int main(int argc, int * argv[]) { //兩個線程啓動同一個函數,f內部實現場景分離 thread t1(f, 0); thread t2(f, 1); thread t3(f, 0); thread t4(f, 1); t1.join(); t2.join(); t3.join(); t4.join(); cout << "main" << endl; system("pause"); }
結果以下:spa
能夠看出,成功實現了不一樣場景下的併發處理,這裏出現亂序的緣由在於cout對象是惟一的,可是未加鎖保護,致使多線程競爭訪問。事實上,f0與f1不該該相同的資源,不然因爲f0與f1未加鎖,會致使資源競爭,這裏僅僅是爲了說明問題,因此使用的cout作打印。這裏的關鍵在於這種場景下的架構與B的實現。線程