【项目-轻量级Web Server lock类】
信号同步机制封装
- Lock类
- 信号量——sem类
- 初始化信号量sem_init()
- 销毁信号量sem_destory()
- 对信号量进行P操作sem_wait()
- 对信号进行V操作sem_post()
- 互斥锁——locker类
- 初始化互斥量pthread_mutex_init()
- 销毁互斥量pthread_mutex_destroy()
- 给互斥锁加锁pthread_mutex_lock()
- 解锁互斥量pthread_mutex_unlock()
- 条件变量——cond类
- 初始化条件变量pthread_cond_init()
- 销毁条件变量对象pthread_cond_destory()
- 唤醒线程pthread_cond_broadcast()
- 阻塞线程pthread_cond_wait()
- 发送信号通知线程pthread_cond_signal()
Lock类
信号量——sem类
信号量是一种特殊的变量,它只能取自然数并且只支持两种操作,P(wait)和V(signal)
-
P 操作会使得信号量的值减 1,如果此时信号量的值小于 0,则调用进程或线程会被阻塞,等待其他进程或线程对信号量进行 V 操作,使得信号量的值大于 0,此时阻塞的进程或线程才能继续执行
-
V 操作会使得信号量的值加 1,如果此时信号量的值小于等于 0,则会唤醒阻塞在该信号量上的某个进程或线程
信号量的取值可以是任何自然数,根据初始值的不同可以分为两类:
-
二进制信号量:指初始值为 1 的信号量,此类信号量只有 1 和 0 两个值,通常用来替代互斥锁实现线程同步
-
计数信号量:指初始值大于 1 的信号量,当进程中存在多个线程,但某公共资源允许同时访问的线程数量是有限的,这时就可以用计数信号量来限制同时访问资源的线程数量
根据使用场景的不同,信号量也可以分为两类:
- 无名信号量:也被称作基于内存的信号量,只可以在共享内存的情况下,比如实现进程中各个线程之间的互斥和同步
- 命名信号量:通常用于不共享内存的情况下,比如进程间通信
在本项目中主要实现的是线程同步,只需要使用无名信号量,主要使用以下几个函数
初始化信号量sem_init()
include <semaphore.h>
int sem_init(sem_t *sem,int pshared,unsignedint value) //初始化一个信号量sem:指向要初始化的信号量的指针
pshared:指定信号量的共享方式。如果值为 0,则信号量将在进程内部共享。如果值为非 0,则信号量可以在不同进程之间共享,需要使用共享内存
value:指定信号量的初值
return:成功则返回0,否则返回-1
销毁信号量sem_destory()
include <semaphore.h>
int sem_destroy(sem_t *sem) //销毁一个信号量sem:指向要销毁的信号量的指针
return:成功返回0,否则返回-1
对信号量进行P操作sem_wait()
include <semaphore.h>
int sem_wait(sem_t *sem) //对信号量进行 P 操作,如果信号量的值小于等于 0,则会阻塞当前线程sem:指向要操作的信号量的指针
return:成功返回0,否则返回-1
对信号进行V操作sem_post()
include <semaphore.h>
int sem_post(sem_t *sem) //对信号量进行 V 操作,如果信号量的值小于等于 0,则会唤醒阻塞在该信号量上的某个线程sem:指向要操作的信号量的指针
return:成功返回0,否则返回-1
互斥锁——locker类
互斥锁,也称互斥量,可以保护关键代码段,以确保独占式访问.当进入关键代码段,获得互斥锁将其加锁;离开关键代码段,唤醒等待该互斥锁的线程
互斥量是一种用于保护临界区的同步机制,可以确保同一时刻只有一个线程访问共享资源。当一个线程访问共享资源时,需要先获取互斥量的锁,其他线程需要等待该锁释放才能继续执行
互斥量不是为了消除竞争,实际上,资源还是共享的,线程间也还是竞争的,只不过通过这种“锁”机制就将共享资源的访问变成互斥操作,也就是说一个线程操作这个资源时,其它线程无法操作它,从而消除与时间有关的错误。但是,这种锁机制不是强制的,互斥锁实质上是操作系统提供的一把“建议锁”(又称“协同锁”),建议程序中有多线程访问共享资源的时候使用该机制
因此,即使有了mutex,其它线程如果不按照这种锁机制来访问共享数据的话,依然会造成数据混乱。所以为了避免这种情况,所有访问该共享资源的线程必须采用相同的锁机制
初始化互斥量pthread_mutex_init()
include <pthread.h>
int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr) //初始化互斥量mutex:指向要初始化的互斥量的指针
attr:指向互斥量属性对象的指针,通常设置为 NULL
return:成功则返回0,否则返回一个正整数的错误码
销毁互斥量pthread_mutex_destroy()
include <pthread.h>
int pthread_mutex_destroy(pthread_mutex_t *mutex) //销毁互斥量mutex:指向要销毁的互斥量的指针
return:成功则返回0,否则返回一个正整数的错误码
给互斥锁加锁pthread_mutex_lock()
include <pthread.h>
int pthread_mutex_lock(pthread_mutex_t *mutex) //给互斥量加锁,如果互斥量已经被锁住,则阻塞当前线程,直到互斥量被解锁mutex:指向要加锁的互斥量的指针
return:成功则返回0,否则返回一个正整数的错误码
解锁互斥量pthread_mutex_unlock()
include <pthread.h>
int pthread_mutex_unlock(pthread_mutex_t *mutex) //解锁互斥量,如果有等待该互斥量的线程,则唤醒其中的一个线程mutex:指向要加锁的互斥量的指针
return:成功则返回0,否则返回一个正整数的错误码
条件变量——cond类
条件变量提供了一种线程间的通知机制,当某个共享数据达到某个值时,唤醒等待这个共享数据的线程
条件变量利用线程间共享的全局变量进行同步,主要包括两个动作:一个线程等待条件变量的条件成立而挂起;另一个线程使条件成立(给出条件成立信号)。为了防止竞争,条件变量的使用总是和一个互斥量结合在一起
初始化条件变量pthread_cond_init()
include <pthread.h>
int pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *attr) //初始化条件变量对象,设置相关属性cond:指向条件变量对象的指针
attr:指向线程条件属性对象的指针。一般为 NULL
return:成功则返回0,失败返回错误号
销毁条件变量对象pthread_cond_destory()
include <pthread.h>
int pthread_cond_destroy(pthread_cond_t *cond) //销毁条件变量对象,释放资源cond:指向条件变量对象的指针
return:成功则返回0,失败返回错误号
唤醒线程pthread_cond_broadcast()
函数以广播的方式唤醒所有等待目标条件变量的线程
include <pthread.h>
int pthread_cond_broadcast(pthread_cond_t *cond) //唤醒所有在条件变量上等待的线程cond:指向条件变量对象的指针
return:成功则返回0,失败返回错误号
阻塞线程pthread_cond_wait()
函数执行时,先把调用线程放入条件变量的请求队列,然后将互斥锁mutex解锁,当函数成功返回为0时,互斥锁会再次被锁上. 也就是说函数内部会有一次解锁和加锁操作
include <pthread.h>
int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex) //让当前线程阻塞在条件变量上等待唤醒cond:指向条件变量对象的指针
mutex:指向互斥锁对象的指针,用于保护条件变量
return:成功则返回0,失败返回错误号
发送信号通知线程pthread_cond_signal()
pthread_cond_signal 只会通知一个等待该条件变量的线程,如果有多个线程在等待,则只有一个线程会收到通知,其余线程还会继续等待,直到下一次收到信号
必须在已经获得与条件变量相关的互斥锁之后才能调用该函数
如果没有等待该条件变量的线程,调用该函数也不会产生任何作用
include <pthread.h>
int pthread_cond_signal(pthread_cond_t *cond)cond:指向条件变量的指针
return:成功则返回0,失败返回错误号
锁机制的功能
锁机制用来实现多线程同步,通过锁机制,确保任一时刻只能有一个线程能进入关键代码段
为便于实现同步类的RAII机制(“Resource Acquisition is Initialization”直译过来是“资源获取即初始化”),该项目在pthread库的基础上进行了封装,实现了类似于C++11的mutex标准库功能
————————————————
源码
/****************locker.h*******************/
#ifndef LOCKER_H
#define LOCKER_H#include <exception>
#include <semaphore.h>
#include <pthread.h>class sem {
public:sem(int value = 0) {if (sem_init(&m_sem, 0, value) != 0) {throw std::exception();}}~sem() {sem_destroy(&m_sem);}bool wait() {return sem_wait(&m_sem) == 0;}bool post() {return sem_post(&m_sem) == 0;}
private:sem_t m_sem;
};class locker {
public:locker() {if (pthread_mutex_init(&m_mutex, NULL) != 0) {throw std::exception();}}~locker() {pthread_mutex_destroy(&m_mutex);}bool lock() {return pthread_mutex_lock(&m_mutex);}bool unlock() {return pthread_mutex_unlock(&m_mutex);}pthread_mutex_t* get() {return &m_mutex;}
private:pthread_mutex_t m_mutex;
};class cond {
public:cond() {if (pthread_cond_init(&m_cond, NULL) != 0) {throw std::exception();}}~cond() {pthread_cond_destroy(&m_cond);}bool wait(pthread_mutex_t* m_mutex) {int ret = pthread_cond_wait(&m_cond, m_mutex);return ret == 0;}bool timewait(pthread_mutex_t* m_mutex, struct timespec t) {return pthread_cond_timedwait(&m_cond, m_mutex, &t);}bool signal() {return pthread_cond_signal(&m_cond) == 0;}bool broadcast() {return pthread_cond_broadcast(&m_cond) == 0;}
private:pthread_cond_t m_cond;
};#endif/*测试locker类代码
// 生产者线程函数
void* producer(void* arg) {block_queue<int>* queue = static_cast<block_queue<int>*>(arg);for (int item = 0; item < 20; item++) {queue->push(item);LOG_INFO("生产者产生数据i = %d", item);usleep((rand() % 5 + 1) * 50000);}return nullptr;
}// 消费者线程函数
void* consumer(void* arg) {block_queue<int>* queue = static_cast<block_queue<int>*>(arg);for (int item = 0; item < 20; item++) {queue->pop(item);LOG_INFO("消费者处理数据i = %d", item);}return nullptr;
}int main() {block_queue<int> queue;pthread_t tid_prod, tid_cons;pthread_create(&tid_prod, nullptr, producer, &queue);pthread_create(&tid_cons, nullptr, consumer, &queue);pthread_join(tid_prod, nullptr);pthread_join(tid_cons, nullptr);return 0;
}
*/
相关文章:

【项目-轻量级Web Server lock类】
信号同步机制封装 Lock类信号量——sem类初始化信号量sem_init()销毁信号量sem_destory()对信号量进行P操作sem_wait()对信号进行V操作sem_post() 互斥锁——locker类初始化互斥量pthread_mutex_init()销毁互斥量pthread_mutex_destroy()给互斥锁加锁pthread_mutex_lock()解锁互…...

数据分析_计划
我做大数据的有6年了,以前都是用sql,或者spark,java,scala,python去做。现在这些平台搭建、维护、大多数都是搭建一次就完了,而且维护大多是大厂直接用云平台去做。ETL也是就做一次就够了,我们公…...

LDAPWordlistHarvester:基于LDAP数据的字典生成工具
关于LDAPWordlistHarvester LDAPWordlistHarvester是一款功能强大的字典列表生成工具,该工具可以根据LDAP中的详细信息生成字典列表文件,广大研究人员随后可以利用生成的字典文件测试目标域账号的非随机密码安全性。 工具特征 1、支持根据LDAP中的详细信…...

dhtmlx-gantt甘特图数据展示
官网文档:甘特图文档 实现效果: 首先需要下载 dhtmlx-gantt组件 npm i dhtmlx-gantt //我项目中使用的是"dhtmlx-gantt": "^8.0.6" 这个版本,不同的版本api或是文档中存在的方法稍有差异 界面引用 <template>&l…...

《云原生安全攻防》-- 容器攻击案例:Docker容器逃逸
当攻击者获得一个容器环境的shell权限时,攻击者往往会尝试进行容器逃逸,利用容器环境中的错误配置或是漏洞问题,从容器成功逃逸到宿主机,从而获取到更高的访问权限。 在本节课程中,我们将详细介绍一些常见的容器逃逸方…...

初学者指南:如何搭建和配置 Nginx 服务器
初学者指南:如何搭建和配置 Nginx 服务器 Nginx 是一个高性能的 HTTP 和反向代理服务器,也是一个 IMAP/POP3/SMTP 代理服务器。本文将详细介绍如何在 Linux 上安装、配置和管理 Nginx 服务器。 一、安装 Nginx Nginx 可以安装在多种操作系统上&#x…...

[AHK] WinHttpRequest.5.1报错 0x80092004 找不到对象或属性
目录 背景描述 用浏览器访问,正常返回 编辑 AHK v2官方示例源代码 AHK v2运行结果报错(0x80092004) 找不到对象或属性 用thqby大佬的WinHttpRequest.ahk库测试报错 0x80092004 找不到对象或属性 附: 用Apifox访问,也正常返回 AHK v1 …...

`speech_recognition` 是一个流行的库
在Python中,speech_recognition 是一个流行的库,用于从各种来源(如麦克风、文件等)进行语音识别。以下是您提到的技术名称和相应的Python代码示例。 技术名称 语音识别(Speech Recognition):这…...

MFC Ribbon菜单 - 中英文实时切换方法
简介 最近在搞一个老外的项目,本来谈的好好的,纯英文界面。项目接近尾声了,又提出了中英文实时切换的新需求,没办法就只能想办法,毕竟客户最大嘛。 实现方法 还好本来的ribbon英文菜单不复杂,就用纯C编码…...

MFC程序创建word,创建表格,写入数据
文章目录 1、MFC程序功能:2、MFC程序实现2.1 创建项目2.2 添加word操作类2.3 添加word资源2.4 编写代码,实现将数据写入到word2.5 运行程序、验证功能3、工程代码下载 1、MFC程序功能: 创建word文档;向文档中写入字符串ÿ…...

FPGA:基于复旦微FMQL10S400 /FMQL20S400 国产化核心板
复旦微电子是国内集成电路设计行业的领军企业之一,早在2000年就在香港创业板上市,成为行业内首家上市公司。公司的RFID芯片、智能卡芯片、EEPROM、智能电表MCU等多种产品在市场上的占有率位居行业前列。 今天介绍的是搭载复旦微 FMQL10S400/FMQL20S400的…...

centos下使用yum安装keepalived工具
1、安装如下rpm包,不安装此包在装keepalived时会报错 mkdir keepalived_rpm cd keepalived_rpm/ wget https://dev.mysql.com/get/Downloads/MySQL-8.0/mysql-community-libs-compat-8.0.36-1.el7.x86_64.rpm 2、使用yum进行keepalived的安装 yum -y install keepal…...

无人机图像目标检测
本仓库是人工智能课程的课程作业仓库,主要是完成无人机图像目标检测的任务,我们对visdrone数据集进行了处理,在yolo和ssd两种框架下进行了训练和测试,并编写demo用于实时的无人机图像目标检测。 requirements依赖: ss…...

JSqlParser 解析 sql
目录 前言一、Maven依赖二、获取sql中的表名三、获取sql中的具体信息 前言 JSqlParser是一个 SQL 语句解析器。它将 SQL 语句转换为可遍历的 Java 类层次结构,可以方便的用代码对 SQL 语句进行解析,修改等操作。 官网 api 文档和 github 地址如下&…...

Vue中使用mind-map实现在线思维导图
概述 在前面的文章Vue中实现在线画流程图实现中介绍了流程图的在线绘制,在本文,给大家分享一下基于mind-map实现在线的思维导图,并实现:1. 导图导出为图片;2. 打开xmind文件。 实现效果 实现 1. mind-map简介 simp…...

ChatGPT 深度解析:技术驱动的智能对话
在当今科技飞速发展的时代,ChatGPT 无疑成为了最耀眼的明星之一。它以其令人惊叹的智能对话能力,引发了全球范围内的广泛关注和热议。 ChatGPT 背后的技术堪称精妙绝伦。它基于深度学习算法,通过对海量数据的学习和分析,从而能够理…...

Armv8-R内存模型详解
目录 1.内存模型的必要性 2.Armv8-R内存模型分类 2.1 Normal memory 2.2 Device Memory 2.2.1 Gathering 2.2.2 Reordering 2.2.3 Early Write Acknowledgement 3.小结 大家好,今天是悲伤的肌肉。 在调研区域控制器芯片时,发现了S32Z、Stellar …...

Python面经
文章目录 Python基本概念1. Python是**解释型**语言还是**编译型**语言2. Python是**面向对象**语言还是面向过程语言3. Python基本数据类型4.append和 extend区别5.del、pop和remove区别6. sort和sorted区别介绍一下Python 中的字符串编码is 和 的区别*arg 和**kwarg作用浅拷…...

海外ASO:iOS与谷歌优化的相同点和区别
海外ASO是针对iOS的App Store和谷歌的Google Play这两个主要海外应用商店进行的优化过程,两个不同的平台需要采取不同的优化策略,以下是对iOS优化和谷歌优化的详细解析: 一、iOS优化(App Store) 1、关键词覆盖 选择关…...

【C++题解】1168. 歌唱比赛评分
问题:1168. 歌唱比赛评分 类型:数组找数 题目描述: 四(1) 班要举行一次歌唱比赛,以选拔更好的苗子参加校的歌唱比赛。评分办法如下:设 N 个评委,打 N 个分数( 0≤每个分…...

鸿蒙开发工程师面试-架构篇
1. 假如让你负责鸿蒙App架构设计,你会关注哪些方面? 分层架构设计: 将应用划分为产品定制层、基础特性层和公共能力层,以降低层间依赖性,提升代码可维护性。通过分层架构设计,进一步明确每层的职责和层间交…...

【Redis】持久化
对于Redis中间件来说,一般是作为内存型数据库或者缓存出现的。但是由于其数据是在内存中,因此当Redis所在的主机宕机之后,数据就会消失,再次重启之后,没有任何数据。这对于生产环境来说,是属于P0级别的灾难…...

港股指数实时行情API接口
港股 指数 实时 行情 API接口 # Restful API https://tsanghi.com/api/fin/index/HKG/realtime?token{token}&ticker{ticker}指定指数代码,获取该指数的实时行情(开、高、低、收、量)。 更新周期:实时。 请求方式:…...

Qt5开发实战_图形_QPen
Qpen是Qt框架中的一个类,用于定义绘制线条的属性,包括颜色、宽度、样式、端点样式和连接样式。 具体属性(设置颜色和设置宽度直接pass从样式开始): 设置样式: pen的样式主要有以下几种: 分别是:直线样式…...

linux进程周边知识——内核对硬件的管理——计算机世界的管理
前言:本节主要讲解内核也就是操作系统对于硬件的管理, 本节内容同样为进程的周边知识。 主要是关于软件方面, 和我的上一篇——冯诺依曼体系结构可以说是兄弟文章, 这篇文章主要是关于硬件方面。 两篇文章都是为学习进程做准备。但…...

同声传译语音合成接口,分段预合成实现丝滑的衔接效果
背景: 在使用微信官方语音合成插件的时候遇到一个问题,textToSpeech这个api的内容限制在官网的文档上明明是1000个字节,也就是说能保证333个中文字符应该是没有问题的,但是也不知道为什么我这里仅仅传了150个中文字符就报错了&…...

数据结构——单链表详解(超详细)(1)
前言: 小编在近日学习了单链表的知识,为了加强记忆,于是诞生了这一篇文章,单链表是数据结构比较重要的知识,读者朋友们一定要去好好的学习!这个可以说是比顺序表更好用的线性表,下面废话不多说&…...

在 Linux 上使用 lspci 命令查看 PCI 总线硬件设备信息
lspci 命令用于显示 Linux 系统上的设备和驱动程序 当在个人电脑或服务器上运行 Linux 时,有时需要识别该系统中的硬件。lspci 命令用于显示连接到 PCI 总线的所有设备,从而满足上述需求。该命令由 pciutils 包提供,可用于各种基于 Linux 和…...

python数据可视化(6)——绘制散点图
课程学习来源:b站up:【蚂蚁学python】 【课程链接:【【数据可视化】Python数据图表可视化入门到实战】】 【课程资料链接:【链接】】 Python绘制散点图查看BMI与保险费的关系 散点图: 用两组数据构成多个坐标点,考察…...

【人工智能】Transformers之Pipeline(二):自动语音识别(automatic-speech-recognition)
目录 一、引言 二、自动语音识别(automatic-speech-recognition) 2.1 概述 2.2 技术原理 2.2.1 whisper模型 2.2.2 Wav2vec 2.0模型 2.3 pipeline参数 2.3.1 pipeline对象实例化参数 2.3.2 pipeline对象使用参数…...