【C++多線程系列】【五】不一樣場景下的多任務併發

有這樣一個場景,底層須要給上層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的實現。線程

相關文章
相關標籤/搜索