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

对锁进行封装

目录

锁的封装

makefile编写

测试运行

RAII式封装


我们今天学习对锁进行封装。

我们在命名空间里面,在自己构建的类mutex里面完成对锁的封装。

锁的封装

我们要进行动态初始化锁,首先要有一个锁对象,所以mutex类里面的私有成员就是锁对象了,然后载初始化里面调用pthread_mutex_init进行初始化,析构函数里面调用pthread_mutex_destroy进行销毁,对锁的操作只需要有解锁和加锁,所以在成员函数lock里面调用pthread_mutex_lock进行加锁,所以在成员函数unlock里面调用pthread_mutex_unlock进行解锁。

#ifndef _THREAD_HPP__
#define _THREAD_HPP__#include<iostream>
#include<pthread.h>
using namespace std;//对锁进行封装namespace lockmodule
{class mutex{public:mutex(){int n = pthread_mutex_init(&_lock, nullptr);(void)n;}void lock(){int n = pthread_mutex_lock(&_lock);(void)n;}void unlock(){int n = pthread_mutex_unlock(&_lock);(void)n;}~mutex(){int n = pthread_mutex_destroy(&_lock);(void)n;}private:pthread_mutex_t _lock;};};#endif

很简单吧,但是由于之前讲过一块临界资源只能有一个锁的,所有线程都只能调用或者间接指向这个锁,所以为了防止锁被拷贝,所以需要将拷贝构造和拷贝赋值给禁用

class mutex{public:mutex(const mutex&) = delete;mutex(mutex&&) = delete; //禁止移动拷贝const mutex& operator= (const mutex&) = delete;const mutex& operator= (mutex&&) = delete; //禁止移动拷贝mutex(){int n = pthread_mutex_init(&_lock, nullptr);(void)n;}

右值的拷贝构造和赋值可以不用,基本没有人会这么调用。

makefile编写

BIN=ticket
CC=g++
SRC = $(wildcard *.cc) 
OBJ = $(SRC:.cc=.o)$(BIN):$(OBJ)$(CC) -o $@ $^ -std=c++17 -lpthread
%.o:%.cc$(CC) -c $< 
.PTHONY:clean
clean:rm -f $(BIN) $(OBJ)

%.o:%.cc这里即使 OBJ 中列出了 .o 文件,make 仍然需要知道如何生成它们, 这行就是在指导make如何生成.o的

OBJ这里:前面的这个范围集合不能有空格。

测试运行

测试代码依旧用的是之间的抢票程序的逻辑,只不过有少许修改。

#include"mutex.hpp"
using namespace lockmodule;
int ticket = 1000;
mutex mtx;
void *route(void *arg)
{char *id = (char *)arg;while (1){mtx.lock();if (ticket > 0){usleep(1000);printf("%s sells ticket:%d\n", id, ticket);ticket--;mtx.unlock();}else{mtx.unlock();break;}}return nullptr;
}
int main()
{pthread_t t1, t2, t3, t4;pthread_create(&t1, NULL, route, (void*)"thread 1");pthread_create(&t2, NULL, route, (void*)"thread 2");pthread_create(&t3, NULL, route, (void*)"thread 3");pthread_create(&t4, NULL, route, (void*)"thread 4");pthread_join(t1, NULL);pthread_join(t2, NULL);pthread_join(t3, NULL);pthread_join(t4, NULL);
}

RAII式封装

我们还可以仿造RAII的形式对锁进行保护,加一个保护类,私有成员自然是这个锁了,然后将一个锁的加锁和解锁分别放在一个这个类的构造和析构函数里面,然后在while循环里面构造保护类的对象,此时由于由于保护类对象属于这个循环区域的,刚刚创建出来的时候会之间构造,调用保护类构造函数加锁之前会先构造这个锁,完成加锁,然后等出了循环自动释放调用析构函数解锁,并调用锁本身的析构函数释放锁资源,从而实现自动加锁+自动释放的RAII形式。

 class lockguard{public:lockguard(mutex& mut):_mut(mut){mut.lock();}~lockguard(){_mut.unlock();}private:mutex& _mut;};
};
#include"mutex.hpp"
using namespace lockmodule;
int ticket = 1000;
mutex mtx;
void *route(void *arg)
{char *id = (char *)arg;while (1){lockguard guard(mtx);if (ticket > 0){usleep(1000);printf("%s sells ticket:%d\n", id, ticket);ticket--;}else{break;}}return nullptr;
}

相关文章:

对锁进行封装

目录 锁的封装 makefile编写 测试运行 RAII式封装 我们今天学习对锁进行封装。 我们在命名空间里面&#xff0c;在自己构建的类mutex里面完成对锁的封装。 锁的封装 我们要进行动态初始化锁&#xff0c;首先要有一个锁对象&#xff0c;所以mutex类里面的私有成员就是锁对…...

【学Rust写CAD】18 定点数2D仿射变换矩阵结构体(MatrixFixedPoint结构别名)

源码 // matrix/fixed.rs use crate::fixed::Fixed; use super::generic::Matrix;/// 定点数矩阵类型别名 pub type MatrixFixedPoint Matrix<Fixed, Fixed, Fixed, Fixed, Fixed, Fixed>;代码解析 这段代码定义了一个定点数矩阵的类型别名 MatrixFixedPoint&#xff…...

C++Primer学习(14.1 基本概念)

当运算符作用于类类型的运算对象时&#xff0c;可以通过运算符重载重新定义该运算符的含义。明智地使用运算符重载能令我们的程序更易于编写和阅读。举个例子&#xff0c;因为在Sales_item类中定义了输入、输出和加法运算符&#xff0c;所以可以通过下述形式输出两个Sales_item…...

接龙数列(最长上升 动规)

问题描述 对于一个长度为 KK 的整数数列&#xff1a;A1,A2,…,AKA1​,A2​,…,AK​&#xff0c;我们称之为接龙数列当且仅当 AiAi​ 的首位数字恰好等于 Ai−1Ai−1​ 的末位数字 (2≤i≤K)(2≤i≤K)。例如 12,23,35,56,61,1112,23,35,56,61,11 是接龙数列&#xff1b;12,23,34…...

HTML跑酷

先看效果 再上代码 <!DOCTYPE html> <html> <head><title>火柴人跑酷</title><style>body {margin: 0;overflow: hidden;background: #87CEEB;}#gameCanvas {background: linear-gradient(to bottom, #87CEEB 0%, #87CEEB 50%, #228B22 …...

ChemBioServer: 一个在线“药物发现/再利用”的平台

ChemBioServer 是一个提供高级化学化合物过滤、聚类和网络分析的服务器&#xff0c;旨在支持药物发现和药物再利用&#xff08;drug repurposing&#xff09;。它集成了多种工具和网络服务&#xff0c;以便更高效地筛选、分析和可视化化学化合物。 网站地址&#xff1a; https:…...

数据结构(4)——带哨兵位循环双向链表

目录 前言 一、带哨兵的循环双向链表是什么 二、链表的实现 2.1规定结构体 2.2创建节点 2.3初始化 2.4打印 2.5检验是否为空 2.6销毁链表 2.7尾插 2.8尾删 2.9头插 2.10头删 2.11寻找特定节点 2.12任意位置插入&#xff08;pos前&#xff09; 2.13删除任意节点 …...

【MyBatis】MyBatis 操作数据库(入门)

文章目录 前言一、什么是MyBatis&#xff1f;二、MyBatis入门2.1、准备工作2.1.1 创建工程2.1.2、数据准备 2.2、配置数据库连接字符串2.3、写持久层代码2.4 单元测试 三、MyBatis的基础操作3.1 打印日志3.2、参数传递3.3、增(Insert)3.4、 删(Delete)3.5、改(Update)3.6、查(S…...

Numpy进行数组函数操作

在编程语言中,数组(Array)是最常用的数据结构之一,它可以存储一系列相同类型的元素,并且通过索引来访问或修改这些元素。在Python中,数组不仅可以通过内置的list数据类型实现,还可以借助第三方库,如NumPy来操作多维数组。掌握数组的内置函数和常用方法是成为熟练程序员…...

高速电路中的存储器应用与设计四

5 SRAM介绍及其应用要点 DRAM的性能在很大程度上受到刷新操作的影响&#xff0c;而SRAM则不涉及刷新&#xff0c;因此在相同时钟频率的条件下&#xff0c;SRAM的性能远高于DRAM。 SRAM的缺点是集成度低、容量小、功耗大、价格高。 在应用的场合上&#xff0c;SRAM毫不逊色于…...

Vue2 项目将网页内容转换为图片并保存到本地

&#x1f31f; 前言 欢迎来到我的技术小宇宙&#xff01;&#x1f30c; 这里不仅是我记录技术点滴的后花园&#xff0c;也是我分享学习心得和项目经验的乐园。&#x1f4da; 无论你是技术小白还是资深大牛&#xff0c;这里总有一些内容能触动你的好奇心。&#x1f50d; &#x…...

汽车加气站操作工证书报考条件是什么?

关于汽车加气站操作工的资格证书&#xff1a; 一、核心证书要求 CNG充装人员上岗证 这是加气站加气工的核心资质证书&#xff0c;需通过专业培训并考核。该证书由相关部门颁发&#xff0c;证明持证人具备从事CNG&#xff08;压缩天然气&#xff09;充装操作的专业技能&#xf…...

动态规划--线性规划

一、https://www.lanqiao.cn/problems/3512/learning/ 解题步骤&#xff1a;1.dp[i]表示以i结尾最长接龙数列长度 2.每读入一个数字x...y&#xff0c;关注头尾的x,y来更新dp[y] 3.dp【y】 max&#xff08;dp【y】&#xff0c;dp【x】1&#xff09;&#xff1a;如果当前数字接…...

HT81697——30W内置升压单声道D类/AB类音频功放

1 特性 ● 防削顶失真功能(防破音,Anti-Clipping Function,ACF) ● 扩频技术 ● 输出功率 28W (VBAT7.2V, RL4Ω, THDN10%, PVDD 15.5V, fiN 1kHz) 22W (VBAT7.2V,RL4Ω, THDN1%, PVDD 15.5V, fin 1kHz) 16.5W (VBAT3.7V, RL4Ω, THDN10%, PVDD 12V, fiN 1kHz) 12.8W (VBAT…...

关于ArcGIS中加载影像数据,符号系统中渲染参数的解析

今天遇到一个很有意思的问题&#xff0c;故记录下来&#xff0c;以作参考和后续的研究。欢迎随时沟通交流。如果表达错误或误导&#xff0c;请各位指正。 正文 当我们拿到一幅成果影像数据的时候&#xff0c;在不同的GIS软件中会有不同效果呈现&#xff0c;但这其实是影像是…...

GAMMA数据处理(十)

今天向别人请教了一个问题&#xff0c;刚无意中搜索到了一模一样的问题 不知道这个怎么解决... ok 解决了 有一个GAMMA的命令可转换 但是很奇怪 完全对不上 转换出来的行列号 不知道为啥 再试试 是因为经纬度坐标的小数点位数 de as...

Spring Boot属性设置方法及优先级完整说明+表格对比

Spring Boot属性设置方法及优先级完整说明 官网参考&#xff1a; https://docs.spring.io/spring-boot/3.4-SNAPSHOT/reference/features/external-config.html#features.external-config.files 属性设置方法优先级顺序&#xff08;从高到低&#xff09; 命令行参数&#xf…...

基于改进粒子群算法的多目标分布式电源选址定容规划(附带Matlab代码)

通过分析分布式电源对配电网的影响&#xff0c;以有功功率损耗、电压质量及分布式电源总容量为优化目标&#xff0c;基于模糊理论建立了分布式电源在配电网中选址定容的多目标优化模型&#xff0c;并提出了一种改进粒子群算法进行求解。在算例仿真中&#xff0c;基于IEEE-14标准…...

SAP 学习笔记 - 系统移行业务 - MALSY(由Excel 移行到SAP 的收费工具)

以前有关移行&#xff0c;也写过一些文章&#xff0c;比如 SAP 学习笔记 - 系统移行业务 - Migration cockpit工具 - 移行Material&#xff08;品目&#xff09;-CSDN博客 SAP 学习笔记 - 系统移行业务 - Migration cockpit工具2 - Lot导入_sap cockpit-CSDN博客 SAP学习笔记…...

2025美国网络专线国内服务商推荐

在海外业务竞争加剧的背景下&#xff0c;稳定高效的美国网络专线已成为外贸企业、跨国电商及跨国企业的刚需。面对复杂的国际网络环境和严苛的业务要求&#xff0c;国内服务商Ogcloud凭借其创新的SD-WAN技术架构与全球化网络布局&#xff0c;正成为企业拓展北美市场的优选合作伙…...

如何正确地在 Postman 中添加认证 Token?

在 Postman 中设置 token。我们知道 HTTP 是无状态的。token 是保持用户的登录状态或者其他数据的一种机制&#xff0c;从而让用户在不同页面之间保持一致的体验。 在 Postman 中添加认证 token 教程...

c++-引用

一、引用的基本概念 引用是C中一种特殊的变量别名机制&#xff0c;本质上是指针常量&#xff08;编译器自动解引用&#xff09;&#xff0c;但语法更简洁安全。 核心特性&#xff1a; 必须初始化&#xff1a;引用在定义时必须绑定到一个已存在的对象。 类型严格匹配&#xf…...

SpringCould微服务架构之Docker(6)

容器的基本命令&#xff1a; 1. docker exec &#xff1a;进入容器执行命令 2. docker logs: -f 持续查看容器的运行日志 3. docker ps&#xff1a;查看所有运行的容器和状态 案例&#xff1a;创建运行一个容Nginx容器 docker run--name myNginx -p 80:80 -d nginx 命…...

Linux|gitlab|二进制快速安装部署gitlab-ce教程

一、 gitlab二进制文件下载地址&#xff1a; 官方网站: gitlab/gitlab-ce - Packages packages.gitlab.com 清华镜像站&#xff1a; Index of /gitlab-ce/yum/ | 清华大学开源软件镜像站 | Tsinghua Open Source Mirror gitlab分为ce也就是社区版本和ee版本&#xff0c;…...

java网盘项目,文件和文件夹用两个表还是一个表,两个表理论查询效率慢了为啥要用,有啥优势

java网盘项目&#xff0c;文件和文件夹用两个表还是一个表&#xff0c;两个表理论查询效率慢了为啥要用&#xff0c;有啥优势 根据网盘系统设计经验与数据库优化原则&#xff0c;独立文件夹表和文件表的设计在复杂场景下具有显著优势。以下是分表方案的核心价值与效率优化策略…...

NixVis 开源轻量级 Nginx 日志分析工具

NixVis NixVis 是一款基于 Go 语言开发的、开源轻量级 Nginx 日志分析工具&#xff0c;专为自部署场景设计。它提供直观的数据可视化和全面的统计分析功能&#xff0c;帮助您实时监控网站流量、访问来源和地理分布等关键指标&#xff0c;无需复杂配置即可快速部署使用。 演示…...

vscode正则表达式使用

小标题 ^\d.\d.\d\s.*$ ^表示匹配字符串的开头。\d\.\d\.\d表示匹配一到多个数字&#xff0c;接着一个小数点&#xff0c;再接着一到多个数字&#xff0c;然后又一个小数点和一到多个数字&#xff0c;用来匹配类似 “2.1.1” 这样的标题号部分。\s表示匹配一个空格。.*表示匹配…...

OpenAI API - Realtime 实时

文章目录 实时 API&#xff08;Beta&#xff09;使用实时API入门示例应用合作伙伴集成 用例通过 WebRTC 连接概述连接详情创建一个临时token发送和接收事件 使用 WebSockets 连接概述连接详情 实时对话Beta实时语音到语音会话会话生命周期事件文本输入和输出音频输入和输出语音…...

PE文件(十三)资源表

所谓的资源也就是我们之前学的MFC中的对话框&#xff0c;按钮&#xff0c;编辑框之类的东西。不仅MFC有资源&#xff0c;我们平时熟悉的控制台程序也有资源 当我们平时写一些程序或者木马时&#xff0c;我们通常对其定义一个随机的名称或者路径&#xff0c;然后再向外界进行释…...

丝杆升降机行程控制:精准运行的奥秘

丝杆升降机作为机械传动领域的 “得力干将”&#xff0c;在环保设备、工业生产线、建筑施工等众多场景中发挥着关键作用。其能够实现重物的升降、平移等操作&#xff0c;而行程控制对于丝杆升降机而言&#xff0c;就如同给机器设定了行动边界&#xff0c;不仅关乎设备能否精准达…...