c语言 多线程 多任务,【C++多线程系列】【五】不同场景下的多任务并发

这篇博客讨论了如何在C++中设计一个并发安全的接口,使得底层的不同实现(如C和D)能够根据上层传入的场景ID动态调用。通过使用`std::lock_guard`确保线程安全,避免了资源竞争。示例展示了如何在多线程环境中使用线程库实现并发控制,并分析了输出结果,揭示了并发编程中的同步问题和解决方案。
摘要由CSDN通过智能技术生成

有这样一个场景,底层需要给上层A提供一套c语言接口,共上层A的C++调用。而上层是并发的,在不同场景下,底层接口是不相同的,比如C与D,上层C++接口不能直接看到底层的不同实现,而是应该上层接口调用下层接口时,传入一个场景id给B,有B来负责依据id来调用C还是D。所以,由于A支持并发,所以B不能阻塞,同时A可以保证,C或者D只能同时被一个线程访问,由于不放心A,所以B自己对C与D做了加锁操作。使用C++ STL中的线程库实现。

cf41a6751a1c4c54cbc2cbdc3cbdfa0b.png

【问题一】C++对象的析构

#include

#include

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");

}

结果如下:

cb9d2be5e6c6a020b710a1c6b13ef920.png

可以看出,该对象的作用域为{},该问题是为了验证下面的lock_guard的能正确的加锁与解锁。

【二】实现上图A B C/D的架构

#include

#include

#include

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 _1(mA);

f0();

}

else {

//分场景加锁保护

std::lock_guard _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");

}

结果如下:

88d5426f02084bcf20cc6050ef3fe808.png

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值