当前位置: 首页 > news >正文

【Linux系统编程】用互斥量和信号量加锁STL容器,避免并发问题

目录

引言

容器模型

容器代码


个人主页:东洛的克莱斯韦克-CSDN博客

引言

STL容器并没有保证线程安全,而大多数应用场景下,为了追求效率,多线程是必不可少的。而底层容器难免会有并发问题。从设计上来说要么在上层代码做加锁处理,要么封装出能保证线程安全容器。

本文给出的方案是用信号量和互斥量封装vector容器——用两个信号量和两个互斥量封装出环形队列。

容器模型

给容器设计两个接口,push()用来向容器填充数据,pop用来向容器取数据。调用push接口的称为生产者,调用pop接口的称为消费者。

vector容器用下标回绕的方式,在逻辑上是一个环形。线程先去申请信号量资源,申请到了信号量资源的线程再去竞争互斥量,谁能锁住互斥量,谁就去容器里操作。

有了信号量和互斥量的存在,在任意时刻,有且只能有0或1个生产者,0或1个消费者线程在容器里操作。那么push接口和pop接口就是原子性的操作。

容器代码

#pragma once // 防止头文件被重复包含
//保证线程安全的环形队列容器
#include <vector>
#include <semaphore.h>
#include <pthread.h>#define C_MAX 300 //容器的容量template <class T>
class annular
{public:annular(int max_c = C_MAX): max_capacity(max_c), min_capacity(0), _c_subscript(0), _p_subscript(0){_v.reserve(max_c);pthread_mutex_init(&_c_lock, nullptr);pthread_mutex_init(&_p_lock, nullptr);sem_init(&_c_sem, 0, 0);sem_init(&_p_sem, 0, max_c);}~annular(){pthread_mutex_destroy(&_c_lock);pthread_mutex_destroy(&_p_lock);sem_destroy(&_c_sem);sem_destroy(&_p_sem);}void push(const T &data){sem_wait(&_p_sem);            // 信号量的p操作pthread_mutex_lock(&_p_lock); // 加锁_v[_p_subscript] = data;_p_subscript++;_p_subscript %= max_capacity;sem_post(&_c_sem);              // 信号量的v操作pthread_mutex_unlock(&_p_lock); // 解锁}void pop(T &data){sem_wait(&_c_sem);            // 信号量的p操作pthread_mutex_lock(&_c_lock); // 加锁data = _v[_c_subscript];_c_subscript++;_c_subscript %= max_capacity;sem_post(&_p_sem);              // 信号量的v操作pthread_mutex_unlock(&_c_lock); // 解锁}private:pthread_mutex_t _c_lock; // 消费者互斥量pthread_mutex_t _p_lock; // 生产者互斥量sem_t _c_sem;            // 消费者信号量sem_t _p_sem;            // 生产者信号量int _c_subscript;        // 消费者下标int _p_subscript;        // 生产者下标std::vector<T> _v;int max_capacity; // 容器最大容量int min_capacity; // 容器最小容量
};

http://www.mrgr.cn/news/28732.html

相关文章:

  • 【数据结构】堆
  • 深入解释synchronized底层原理
  • QT 事件 Event 应用
  • 2010-2022 CSP-J/普及组T1-T4考点统计
  • C++:多态
  • 补题篇--codeforces
  • 论文笔记:交替单模态适应的多模态表征学习
  • python贪吃蛇游戏项目源码【免费】
  • 中秋的“超级月亮”在哪?来竹海幻境寻找心中的白月光
  • 基于SSM的在线家用电器销售系统
  • 这个时代唯一“不变“的又是{变}
  • @EnableScheduling 和 @Scheduled 实现定时任务的任务延期问题
  • 459. 重复的子字符串
  • Defining Constraints with ObjectProperties
  • 【C++】—— list 模拟实现
  • golang学习笔记19——golang做服务发现与注册的深度剖析
  • 信奥学习规划(CSP-J/S)
  • 南京信息工程大学《2020年+2021年817自动控制原理真题》 (完整版)
  • javascript中==和===的区别以及使用场景
  • Openal o1初探