[modern c++] 细粒度锁的concurrency数据结构

前言

https://blog.csdn.net/ykun089/article/details/115349993 中描述的是 serilization 模式的数据结构,其锁的粒度很粗,虽然说是多线程安全的,但是无法进行并发(concurrency)访问,从而导致同一时刻只能有一个线程在操作数据结构。

如果想实现并发访问,一种是使用细粒度锁的数据结构,另一种就是无锁的数据结构设计。其实细粒度锁属于 “伪并发”,它在是否能真正设计成并发需要视应用场景而定。

虽然都有锁,粗粒度锁就是串行化访问,细粒度锁通过对具体应用场景的分析可以做到一定程度上的 “伪并发”。

 

注:以下代码均摘自 《C++ Concurrency In Action》

 

局部加锁的队列:

#pragma once

#include <queue>
#include <memory>


template <typename T>
class threadsafe_queue 
{
private:
	struct node {
		std::shared_ptr<T> data;

		//为什么要用unique_ptr,如果想做细粒度的锁控制,那么unique_ptr是必须的,细粒度控制意味着局部加锁,且各个动作之前应当是互不干扰的
		//比如pop只操作队列头部,push只操作队列尾部,这样的话就可以保证生产者线程(调用push的线程)和消费者线程(调用pop的线程)可以完全并发
		//进行。但是多个生产者之间还是需要同步,多个生产者之间也需要互相同步,且同步使用的就是局部锁。
		//unique_ptr可以保证指针不会被导出,这样的话外部就无法对指针额外加锁和销毁指针。
		//局部锁是并发访问的理论基础。
		//并发访问的核心思想就是通过为固有/常见的数据结构添加一些辅助节点,以实现生产者和消费者的访问隔离,在此基础上,如果有多个生产者和多个
		//消费者,则只提供生产者同步锁和消费者同步锁即可。
		std::unique_ptr<node> next;			
	};

	std::mutex head_m;
	std::mutex tail_m;
	std::unique_ptr<node> head;
	node* tail;

	node* get_tail() 
	{
		std::lock_guard<std::mutex> lock_tail(tail_m);
		return tail;
	}

	std::unique_ptr<node> pop_head()
	{
		std::lock_guard<std::mutex> lock_head(head_m);

		if (head.get() == get_tail()) {
			return nullptr;
		}

		std::unique_ptr<node> old_head = std::move(head);
		head = std::move(old_head->next);
		return old_head;
	}

public:
	threadsafe_queue()
		:head(new node)
		, tail(head.get())
	{}

	threadsafe_queue(const threadsafe_queue& other) = delete;
	threadsafe_queue& operator=(const threadsafe_queue& other) = delete;

	std::shared_ptr<T> try_pop() 
	{
		std::unique_ptr<node> old_head = pop_head();
		return old_head ? old_head->data : std::shared_ptr<T>();
	}

	void push(T new_value) 
	{
		std::shared_ptr<T> new_data(std::make_shared<T>(std::move(new_value)));
		std::unique_ptr<node> p(new node);
		node* const new_tail = p.get();
		std::lock_guard<std::mutex> tail_lock(tail_m);
		tail->data = new_data;
		tail->next = std::move(p);
		tail = new_tail;
	}
};









 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值