【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中的线程库实现。

【问题一】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");
}

结果如下:

可以看出,成功实现了不同场景下的并发处理,这里出现乱序的原因在于cout对象是唯一的,但是未加锁保护,导致多线程竞争访问。事实上,f0与f1不应该相同的资源,否则由于f0与f1未加锁,会导致资源竞争,这里仅仅是为了说明问题,所以使用的cout做打印。这里的关键在于这种场景下的架构与B的实现。

猜你喜欢

转载自my.oschina.net/u/3800567/blog/1800660