C++并发编程实战

第3章 线程间共享数据

3.1 共享数据带来的问题

共享数据,但当一个或多个线程要修改数据时,就会产生很多的麻烦。

3.1.1 条件竞争

并发中竞争条件的形成,取决于一个以上线程的相对执行程序,每个线程都要抢着完成自己的任务。(这很好理解,就比如去电影院买电影票一样,剩下最后一张,抢票大战。。。)

3.1.2 避免恶行条件竞争

最简单的方法:对数据结构采用某种保护机制,确保只有进行修改的线程才能看啊都不变量被破坏的中间状态。
另一个选择是:对数据结构和不变量的设计进行修改,形成一系列不可分割的变化,并且处于稳定状态。
另外一个方式:使用事务的方式处理数据结构的更新(STM software transactional memory 软件事务内存)
保护共享数据结构的最基本的方式:是使用C++标准库提供的互斥量

3.2 使用互斥量保护共享数据

过程:访问共享数据前–>将数据锁住—>访问结束后—>将数据解锁
互斥量:需要编排代码保护数据的正确性(3.2.2节)
需要避免接口间的竞争条件
缺点:造成死锁、对数据保护的太多(太少)(见 3.2.8节)

3.2.1 C++使用互斥量

实例化std::mutex创建互斥量实例,用lock()对互斥量上锁,unlock进行解锁。不过,在实践时要调用函数就要每个函数出口要调用unlock(),麻烦。
C++标准库为互斥量提供了RAII语法的模板类std::lock_guard,在构造时已提供互斥量,析构时进行解锁

//清单3.1 使用互斥量保护列表
#include<list>
#include<mutex>
#include<algorithm>

std::list<int> some_list;
std::mutex some_mutex;

void add_to_list(int new_value)
{
	std::lock_guard<std::mutex> guard(some_mutex);
	some_list.push_back(new_value);
}

bool list_contains(int value_to_find)
{
	std::lock_guard<std::mutex> guard(some_mutex);
	return std::find(some_list.begin(),some_list.end(),value_to_find) != some_list.end();
}
//add_to_list()和list_contains()函数中使用std::lock_guard<std::mutex>,
//让这两个函数对数据访问互斥,后者看不到前者正修改而定列表

后面有C++17中的一种加强版保护数据机制std::scoped_lock (std::scoped_lock guard (std::mutex))
小李子(未上锁)

#include<iostream>
#include<string>
#include<thread>
using namespace std;
void thread_task() {
	for (int i = 0; i < 10; i++)
	{
		cout << "print thread:" << i << endl;
	}
}
int main() {
	thread t(thread_task);
	for (int i = 0; i > -10; i--) {
		cout << "print main:" << i << endl;
	}
	t.join();
	return 0;
}
//结果:
/*
print main:0
print main:-1
print main:-2
print main:-3
print main:-4
print main:-5
print main:-6
print main:-7
print main:-8
print main:-9
print thread:0
print thread:1
print thread:2
print thread:3
print thread:4
print thread:5
print thread:6
print thread:7
print thread:8
print thread:9
*/

3.2.2 用代码来保护共享数据

四级标题
五级标题
六级标题
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值