Linux 无名信号量(Semaphore)的使用

目录

  • 一、无名信号量的概念
  • 二、无名信号量相关函数
  • 三、信号量的使用步骤
  • 四、应用场景
  • 五、测试代码

一、无名信号量的概念

Linux无名信号量(Semaphore)
  在Linux操作系统中,信号量(Semaphore)是一种用于进程间或线程间同步和互斥的工具。无名信号量(也被称为POSIX信号量)是POSIX标准的一部分,与System V信号量相比,它提供了更丰富的功能和更好的可移植性。
  无名信号量是一种用于控制多个线程进程对共享资源的访问的计数器。它通常用于实现两个功能。
同步:确保进程或线程以特定的顺序访问资源。
互斥:防止两个或多个进程或线程同时访问共享资源。
  信号量的值是一个非负整数,通常被称为“许可数”或“资源数”。当信号量的值为0时,表示没有资源可用;当信号量的值大于0时,表示有相应数量的资源可用。

二、无名信号量相关函数

无名信号量相关函数如下
sem_init():初始化一个无名信号量。
sem_destroy():销毁一个无名信号量。
sem_wait()(也称为sem_trywait()或sem_timedwait()):尝试减少信号量的值。如果信号量的值大于0,则将其减1并立即返回;如果信号量的值为0,则进程将被阻塞,直到信号量的值变为非零。
sem_post():增加信号量的值。这通常表示释放了一个资源。

头文件

#include <semaphore.h>

函数的详细内容,可查看手册,如 sem_wait() 函数,介绍如下:
在这里插入图片描述

三、信号量的使用步骤

使用信号量的步骤
①在程序全局区定义信号量;
②使用 sem_init()初始化信号量;
③ 使用 sem_wait()和 sem_post()对信号量进行 P/V 操作;
④ 使用 sem_destroy()销毁信号量。

四、应用场景

无名信号量在多线程编程和进程间通信(IPC)中非常有用。以下是一些可能的应用场景:
生产者-消费者问题:生产者生成数据项并将其放入缓冲区,而消费者从缓冲区中取出数据项并处理它们。使用信号量可以确保生产者在缓冲区满时不会写入数据,而消费者在缓冲区空时不会尝试读取数据。
读写锁:多个线程可以同时对共享资源进行读操作,但在写操作期间需要阻止其他线程进行读或写操作。信号量可以用于实现这种读写锁。

五、测试代码

  程序创建了一个生产者线程和一个消费者线程,线程间通过一个固定大小的缓冲区进行通信。生产者生产整数并将其放入缓冲区,而消费者从缓冲区中取出整数并打印。通过使用信号量empty和full,可以确保生产者不会在缓冲区满时写入数据,而消费者不会在缓冲区空时尝试读取数据。

#include <stdio.h>  
#include <stdlib.h>  
#include <pthread.h>  
#include <semaphore.h>  #define BUFFER_SIZE 10  int buffer[BUFFER_SIZE];  
int in = 0, out = 0;  
sem_t empty, full;  void *producer(void *arg) {  for (int i = 0; i < 20; i++) {  sem_wait(&empty);  // 等待缓冲区有空位  buffer[in] = i;  printf("Producer produced %d\n", i);  in = (in + 1) % BUFFER_SIZE;  sem_post(&full);   // 表示缓冲区有一个新项  }  return NULL;  
}  void *consumer(void *arg) {  for (int i = 0; i < 20; i++) {  sem_wait(&full);   // 等待缓冲区有项  int item = buffer[out];  printf("Consumer consumed %d\n", item);  out = (out + 1) % BUFFER_SIZE;  sem_post(&empty);  // 表示缓冲区有一个空位  }  return NULL;  
}  int main() {  pthread_t p, c;  sem_init(&empty, 0, BUFFER_SIZE);  // 初始时缓冲区为空,有BUFFER_SIZE个空位  sem_init(&full, 0, 0);             // 初始时缓冲区无项  pthread_create(&p, NULL, producer, NULL);  pthread_create(&c, NULL, consumer, NULL);  pthread_join(p, NULL);  pthread_join(c, NULL);  sem_destroy(&empty);  sem_destroy(&full);  return 0;  
}

测试结果
在这里插入图片描述
线程中加入 sleep() 函数
在这里插入图片描述

代码如下:

#include <stdio.h>  
#include <stdlib.h>  
#include <pthread.h>  
#include <semaphore.h>  
#include <unistd.h>#define BUFFER_SIZE 10  int buffer[BUFFER_SIZE];  
int in = 0, out = 0;  
sem_t empty, full;  void *producer(void *arg) {  for (int i = 0; i < 20; i++) {  sem_wait(&empty);  // 等待缓冲区有空位  buffer[in] = i;  printf("Producer produced %d\n", i);  in = (in + 1) % BUFFER_SIZE;  sem_post(&full);   // 表示缓冲区有一个新项  sleep(1);}  return NULL;  
}  void *consumer(void *arg) {  for (int i = 0; i < 20; i++) {  sem_wait(&full);   // 等待缓冲区有项  int item = buffer[out];  printf("Consumer consumed %d\n", item);  out = (out + 1) % BUFFER_SIZE;  sem_post(&empty);  // 表示缓冲区有一个空位  sleep(1);}  return NULL;  
}  int main() {  pthread_t p, c;  sem_init(&empty, 0, BUFFER_SIZE);  // 初始时缓冲区为空,有BUFFER_SIZE个空位  sem_init(&full, 0, 0);             // 初始时缓冲区无项  pthread_create(&p, NULL, producer, NULL);  pthread_create(&c, NULL, consumer, NULL);  pthread_join(p, NULL);  pthread_join(c, NULL);  sem_destroy(&empty);  sem_destroy(&full);  return 0;  
}

测试结果如下:
在这里插入图片描述
可以看到,第一种程序,因为没有sleep()让出 cpu,会一直生产数据,直到 empty 为空,也就是等待缓冲区空位为0 ,程序阻塞,让出 cpu ,消费者开始进行处理,直到 full 为空,处理完毕,让出 cpu。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/9367.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

内网穿透速度慢

内网穿透速度慢原因及优化策略 在计算机网络应用中&#xff0c;内网穿透是一个常见的需求&#xff0c;它允许外部网络访问位于内部网络&#xff08;如企业局域网或家庭网络&#xff09;中的设备或服务。然而&#xff0c;有时用户在进行内网穿透时会遇到速度慢的问题&#xff0…

AI视频教程下载:给企业管理层和商业精英的ChatGpt课程

课程内容大纲&#xff1a; 1-引言 2-面向初学者的生成性人工智能 3-与ChatGPT一起学习提示101 详细介绍了如何使用ChatGPT的六种沟通模式&#xff0c;并提供了各种实际应用场景和示例&#xff1a; **Q&A模式&#xff08;问题与答案模式&#xff09;**&#xff1a; - 这…

打印机处于脱机状态如何恢复到正常状态?最简单!

当打印机一直处于脱机状态但打印机重启了好几遍仍然无效果时&#xff0c;尝试以下方法或许会成功&#xff01; 1.打开设置&#xff0c;在主页界面会有它的推荐设置&#xff0c;如上图&#xff0c;此时只需要点击“打印机和扫描仪”这个方框即可 2.但也并不是每次都会有推荐设置…

从零开始!学习绘制3D表情的详细指南

在2020 年的苹果全球开发者大会(WWDC)&#xff0c;苹果发布了新的 macOS 11(又名 Big Sur)。其中在UI视觉方面macOS Big Sur 系统最大的变化就是图标上&#xff0c; Big Sur更新了很多新设计风格的 3D应用图标&#xff0c;3D设计的确可以提升UI整体的视觉氛围&#xff0c;并且现…

wsl2安装rancher并导入和创建k8s集群

环境准备 安装wsl2点击此文]ubuntu20.04安装docker 点击此文,安装完成后docker镜像仓库改成阿里云镜像加速地址.如果不熟请点击此文 docker 安装rancher 启动wsl,根据官方文档以root身份执行 sudo docker run -d --restartunless-stopped -p 80:80 -p 443:443 --privileged …

《基于GNU-Radio和USRP的雷达通信系统的实现》文献阅读

文章目录 前言一、摘要二、引言三、联合系统实施1、基本原理2、实验方案 四、软件设置1、发射机2、接收机 五、实验结果1、实验设置2、波形3、室内外对比4、不同参数的结果 六、结论七、参考文献八、论文自取九、阅读收获 前言 本文记录《基于GNU-Radio和USRP的雷达通信系统的实…

2024粤港澳青少年信息学创新大赛C++知识点汇总和真题训练

2024粤港澳青少年信息学创新大赛C知识点汇总和真题训练 知识汇总 真题训练 程序设计语言C是一种解释性语言。 A.正确 B.错误 Python是一种编译型语言。 A.正确 B.错误 误 RAM&#xff08;随机存取存储器&#xff09;是一种易失性存储设备。 A.正确 B.错误 Java…

Docker-harbor

一、搭建本地私有仓库 1.1 下载Registry镜像 1.2 添加本地私有仓库配置 1.3 重启服务并运行Registry容器 1.4.容器的操作 1.4.1 拉取Nginx镜像并为镜像打标签 1.4.2 上传到私有仓库 1.4.3 列出私有仓库所有镜像 1.4.4 列出私有仓库的镜像的所有标签 1.4.5 先删除原有…

基于鸢尾花数据集实施自组织神经网络聚类分析

基于鸢尾花数据集实施自组织神经网络聚类分析 1. 自组织神经网络的基础知识2. 鸢尾花数据集的自组织分类3. SOM的无监督聚类 1. 自组织神经网络的基础知识 自组织神经网络也称自组织映射&#xff08;SOM&#xff09;或自组织特征映射&#xff08;SOFM&#xff09;&#xff0c;…

Coze扣子开发指南:用免费API自己创建插件

虽然Coze扣子现在插件商店已经有几百个插件了&#xff0c;但相对于海量人群的众多差异化需求&#xff0c;还是远远不够的。如果插件商店没有合适的插件&#xff0c;其实完成可以自己创建&#xff0c;过程也很简单&#xff0c;不需要编写任何代码。 首先打开个人空间&#xff0…

AcWing 835:Trie字符串统计 ← 字典树(Trie树)模板题

【题目来源】https://www.acwing.com/problem/content/837/【题目描述】 维护一个字符串集合&#xff0c;支持两种操作&#xff1a; ● I x 向集合中插入一个字符串 x&#xff1b; ● Q x 询问一个字符串在集合中出现了多少次。 共有 N 个操作&#xff0c;所有输入的字符…

Linux sudo 指令

sudo命令 概念&#xff1a; sudo是linux下常用的允许普通用户使用超级用户权限的工具&#xff0c;允许系统管理员让普通用户执行一些或者全部的root命令&#xff0c;如halt&#xff0c;reboot&#xff0c;su等。这样不仅减少了root用户的登录和管理时间&#xff0c;同样也提高…

22、Flink 背压下的 Checkpoint处理

1.概述 通常&#xff0c;对齐 Checkpoint 的时长主要受 Checkpointing 过程中的同步和异步两个部分的影响&#xff1b;但当 Flink 作业正运行在严重的背压下时&#xff0c;Checkpoint 端到端延迟的主要影响因子将会是传递 Checkpoint Barrier 到 所有的算子/子任务的时间&…

线程与进程

进程 进程是程序的一次执行过程&#xff0c;系统程序的基本单位。有自己的main方法&#xff0c;并且主要由主方法运行起来的基本上就是进程。 线程 线程与进程相似&#xff0c;但线程是一个比进程更小的执行单位。一个进程在其执行的过程中可以产生多个线程。与进程不同的是…

局域网语音对讲系统_IP广播对讲系统停车场解决方案

局域网语音对讲系统_IP广播对讲系统停车场解决方案 需求分析&#xff1a; 随着国民经济和社会的发展&#xff0c; 选择坐车出行的民众越来越多。在保护交通安全的同时&#xff0c;也给停车场服务部门提出了更高的要求。人们对停车场系统提出了更高的要求与挑战&#xff0c; 需要…

部分设计模式概述

单例模式 工厂模式 适配器模式 模板方法模式 策略模式 责任链 观察者模式&#xff08;又叫发布订阅模式&#xff09;

容器化Jenkins远程发布java应用(方式一:pipline+ssh)

1.创建pipline工程 2.准备工程Jenkinsfile文件&#xff08;java目录&#xff09; 1.文件脚本内容 env.fileName "planetflix-app.jar" env.configName "planetflix_prod" env.remoteDirectory "/data/project/java" env.sourceFile "/…

Leetcode - 周赛396

目录 一&#xff0c;3136. 有效单词 二&#xff0c;3137. K 周期字符串需要的最少操作次数 三&#xff0c;3138. 同位字符串连接的最小长度 四&#xff0c;3139. 使数组中所有元素相等的最小开销 一&#xff0c;3136. 有效单词 本题就是一道阅读理解题&#xff1a; 字符串长…

NSSCTF | [SWPUCTF 2021 新生赛]easy_sql

打开题目&#xff0c;提示输入一些东西&#xff0c;很显眼的可以看到网站标题为“参数是wllm” 首先单引号判断闭合方式 ?wllm1 报错了&#xff0c;可以判断为单引号闭合。 然后判断字节数&#xff08;注意‘--’后面的空格&#xff09; ?wllm1 order by 3-- 接着输入4就…

vue多选功能

废话不多说&#xff0c;直接上代码&#xff01;&#xff01;&#xff01; <template><div class"duo-xuan-page"><liv-for"(item, index) in list":key"index"click"toggleSelection(item)":class"{ active: sel…