Linux——进程间通信,信号量的使用+小demo(C语言)

news2025/1/19 22:09:53

一.什么是信号量呢?用途又是什么呢?

        信号量就是解决进程之间竞争资源的情况,比如:我们在宿舍用的公共洗衣机,我们只有当它空闲的时候,我们才可以去使用它,当别人看到洗衣机在使用的时候,就不能再去使用了。这个例子中,洗衣机就是资源,每个想洗衣服的人都想去占用资源。但是我们得等当前的前一个人洗完才可以使用,这就是等待。

        首先我们来看Linux下的几个信号量相关的函数:

1.int semget(key_t key, int nsems, int semflg);

这个函数可以用来初始化信号量或者获得当前的信号量,当无法初始化的时候,返回的值为-1。使用时是这样。第一个参数是设置key_t的值,第二个是信号量的个数。第三个是通过bash来获取信号量的信息。

semid = semget((key_t)1234, 1, IPC_CREAT | IPC_EXCL | 0600);//用来初始化信号量,如果信号量的key_t值已存在的话就返回-1
semid = semget((key_t)1234, 1, 0600);//获取已经存在信号量的key_t值,如果已存在返回当前key_t。如果没有,返回-1

2.semctl(int semid, int semnum, int cmd, ...);

返回的是当前信号量的key值(usigned int)类型的,通常用获取或者删除某个信号量,使用方法如下

semctl(semid, 0, SETVAL, a)//这个是初始化当前semid信号量第0+1个元素的值,a为下方结构体
           union semun {
               int              val;    /* Value for SETVAL */
               struct semid_ds *buf;    /* Buffer for IPC_STAT, IPC_SET */
               unsigned short  *array;  /* Array for GETALL, SETALL */
               struct seminfo  *__buf;  /* Buffer for IPC_INFO
                                           (Linux-specific) */
           };//需要程序员去定义
semctl(semid, 0, IPC_RMID);//这个是删除当前semid对应的信号量

  3. semop(semid, &buf, 1) ;(这些函数都可以通过bash命令man来找到原型)

用来获取或者释放当前资源,其中buf是定义好的结构体,结构体成员sem_op为1的时候就是释放资源,为-1则是占用资源

struct sembuf buf;
  buf.sem_num = 0;
  buf.sem_op = 1;
  buf.sem_flg = SEM_UNDO;
semop(semid, &buf, 1);//第一个参数是当前信号量的id,第二个参数就是提到的结构体,第三个参数是如果程序异常退出的话,我们可以释放它所占用的资源

4.Ok,逻辑成立,理论实践。

        介绍一下文件的结构把,先来编辑

只看.从.c和.h文件,文字描述一下把。sem.h文件中声明了四个方法,比如信号量的初始化,资源的释放和占用,信号量的销毁、

sem.c文件就是队sem.h头文件的实现。

main.c和test.c就是两个进程,我们两个进程都占用屏幕来输出,但是我们再同一时间,只想让一个进程来使用我们的屏幕,这就得用来我们的信号量。下面我们来看一看各个文件的具体实现把。

 1.sem.h

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/sem.h>

union semun {
  int val;
};

void sem_init();
void sem_p();
void sem_v();
void sem_destory();

2.sem.c

#include "sem.h"
#include <sys/sem.h>
#include <sys/types.h>

static int semid = -1;

void sem_init() {
  semid = semget((key_t)1234, 1, IPC_CREAT | IPC_EXCL | 0600);
  if (semid == -1) {
    semid = semget((key_t)1234, 1, 0600);
    if (semid == -1) {
      printf("semget err\n");
    }
  } else {
    union semun a;
    a.val = 1;
    if (semctl(semid, 0, SETVAL, a) ==
        -1) { //此时我们只需要一个变量,所以下标为0
      printf("semctl err\n");
    }
  }q
}
void sem_p() {
  struct sembuf buf;
  buf.sem_num = 0;
  buf.sem_op = -1;
  buf.sem_flg = SEM_UNDO;
  if (semop(semid, &buf, 1) == -1) {
    printf("p err\n");
  }
}
void sem_v() {
  struct sembuf buf;
  buf.sem_num = 0;
  buf.sem_op = 1;
  buf.sem_flg = SEM_UNDO;
  if (semop(semid, &buf, 1) == -1) {
    printf("v err\n");
  }
}
void sem_destory() {
  if (semctl(semid, 0, IPC_RMID) == -1) {
    printf("semvtl err\n");
  }
}

3.main.c

#include "sem.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
int main() {
  sem_init();
  for (int i = 0; i < 5; i++) {
    sem_p();
    printf("B");
    fflush(stdout);
    int n = rand() % 3;
    sleep(n);
    printf("B");
    fflush(stdout);
    sem_v();
    sleep(n);
  }
  sleep(10);
  sem_destory();
}

4.test.c

#include "sem.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
int main() {
  sem_init();
  for (int i = 0; i < 5; i++) {
    sem_p();
    printf("A");
    fflush(stdout);
    int n = rand() % 3;
    sleep(n);
    printf("A");
    fflush(stdout);
    sem_v();
    sleep(n);
  }
}

5.进程间通信几个文件进行运行的话和普通文件的编译也不一样,所以CV之前的代码只是半九十,我们来看一下编译吧

这是编译时候的代码 ,运行结果如下,最后一行的最左侧有个B,别忘记了。困惑了我半天。

 

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

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

相关文章

LVS负载均衡群集部署(DR模式)

一.DR模式 LVS负载均衡群集部署 ipvsadm 工具选项说明&#xff1a; 工具选项作用-A添加虚拟服务器-D删除整个虚拟服务器-s指定负载调度算法&#xff08;轮询&#xff1a;rr、加权轮询&#xff1a;wrr、最少连接&#xff1a;lc、加权最少连接&#xff1a;wlc&#xff09;-a表示…

clickhouse-MergeTree

创建建表语句 create table t_order_mt(id UInt32,sku_id String,total_amount Decimal(16,2),create_time Datetime ) engine MergeTreepartition by toYYYYMMDD(create_time)primary key (id)order by (id,sku_id); 插入测试数据 insert into t_order_mt(id,sku_id,total_…

chatgpt赋能python:Python数据分析必备工具:Pandas

Python数据分析必备工具&#xff1a;Pandas Python作为一门流行的编程语言&#xff0c;广泛应用于数据科学领域。而Pandas作为Python语言下的数据分析库&#xff0c;被广泛地应用于数据处理、数据分析、数据可视化等方面。本文将介绍如何快速地入门Pandas并进行数据分析。 什…

《统计学习方法》——逻辑斯谛回归与最大熵模型(下)

最大熵模型 极大似然估计 下面证明对偶函数的极大化等价于最大熵模型的极大似然估计。 极大似然估计的思想就是通过概率最大化来求出最符合的分类。对应的步骤为&#xff1a; 根据训练集&#xff0c;写出不同分类下的概率函数将不同分类下的概率函数进行汇总&#xff0c;写…

[hsctf 2023] crypto,pwn,rev部分

刚完了天津又来个衡水,这个大部分题比较简单,最后两天整了3个crypto有点意思. crypto double-trouble 给了密文 Hvwg gvcizr bch ps hcc vofr. Wb toqh, W kwzz uwjs wh hc mci fwuvh bck! Hvs tzou wg hvs tczzckwbu: OmqemdOubtqdeMdqOaax Vcksjsf, wh wg sbqcrsr gc mci …

刷脸登录(人工智能)

刷脸登录 理解刷脸登录的需求 理解刷脸登录的开发流程实现刷脸登录功能 浅谈人工智能 人工智能的概述 人工智能&#xff08;Artificial Intelligence&#xff09;&#xff0c;英文缩写为AI。它是研究、开发用于模拟、延伸和扩展人的智能的理论、方法、技术及应用系统的一门…

chatgpt赋能python:Python怎么下pip:简单又方便的工具

Python怎么下pip&#xff1a;简单又方便的工具 Python 是一门广泛应用的高级编程语言&#xff0c;它设计的初衷是让程序员更加愉悦地编写代码&#xff0c;同时提供了多种强大的库和框架。其中&#xff0c;pip 是最为常见的第三方包管理工具&#xff0c;本文将为你介绍如何下载…

uniapp实现主题切换功能实现第一种方式(scss变量+vuex)

随着用户端体验的不断提升&#xff0c;很多应用在上线的时候都要求做不同的主题&#xff0c;最基本的就是白天与夜间主题。 就像b站app主题切换&#xff0c;像这样的 uniapp因为能轻松实现多端发布而得到很多开发者的青睐&#xff0c;但每个端的实现也有可能不同&#xff0c;现…

NLP学习笔记四-word embeding

NLP学习笔记四-word embeding word embeding就是一块重头戏了&#xff0c;因为这里做完&#xff0c;我们的数据处理部分也基本上收尾了。 下面我们附上一张图&#xff1a; 如上图&#xff0c;word embeding实在我们one-hot word之后才可以进行的&#xff0c;每一步处理技术都是…

NVM安装(管理Node.js版本)

NVM可以在一台电脑上安装多个版本Node.js&#xff0c;并且可以一条指令随时下载或切换版本 下载安装 github下载地址&#xff1a;https://github.com/coreybutler/nvm-windows/releases 一路next&#xff0c;注意修改安装路径即可&#xff08;不要安装在有中文名称的目录下&am…

Latex图表制作:关于EPS文件转PDF文件及PDF裁剪自动化的Shell脚本制作

关于EPS文件转PDF文件及PDF裁剪自动化的Shell脚本制作 前言一、EPS文件转PDF文件1. 过去的科研绘图方案2. 未来的科研绘图方案 二、使用步骤1. 单例操作a. 安装epstoolb. 切除EPS文件白边并保存临时EPS文件d. 将EPS文件转换为PDF文件 2. 批处理操作a. Shell 脚本b. 使用说明 参…

贝叶斯公式的理解与推导(简单版本)

院子里面有条狗&#xff0c;过去几十年中&#xff0c;平均100天狗会叫50天&#xff0c;平均100天被偷盗一次&#xff0c;偷盗时有90%概率狗会叫&#xff0c;请问当狗叫的时候&#xff0c;是小偷入侵的概率有多大&#xff1f; 分析&#xff1a; 狗叫为独立事件A&#xff0c;偷盗…

chatgpt赋能python:Python如何将PDF转换为Word文档

Python如何将PDF转换为Word文档 在现代电脑使用的日常工作中&#xff0c;PDF格式的文档已经变得很普遍。这种文件格式十分方便&#xff0c;但是有时候可能需要将PDF文件转换为Word文档。幸运的是&#xff0c;Python提供了多种方法来实现这个目标。 为什么要将PDF转换为Word&a…

6. 常见的文件编码方式及查看网页源码的编码方式

6. 常见的文件编码方式及查看网页源码的编码方式 文章目录 6. 常见的文件编码方式及查看网页源码的编码方式1. 编码的由来2. 编码的作用3. 常见的编码方式4. ASCII码5. Unicode符号集6. UTF-87. GB23128. GBK9. ISO-8859-110. 文件编码查看方式11. 网页编码查看方式12. 留言 1.…

【学习日记2023.6.9】之 SpringCloud入门

文章目录 SpringCloud1. 认识微服务1.1 单体架构1.2 分布式架构1.3 微服务1.4 SpringCloud1.5 总结 2. 服务拆分和远程调用2.1 服务拆分原则2.2 服务拆分示例2.2.1 导入Sql语句2.2.2 导入demo工程 2.3 实现远程调用案例2.3.1 案例需求&#xff1a;2.3.2 注册RestTemplate2.3.3 …

计算机组成原理——总线,输入输出系统

文章目录 **一 总线概述****1 总线基本概念****1.1 定义****1.2 总线设备****1.3 总线特性** **2 总线的分类****2.1 片内总线****2.2 系统总线****2.3 I/O总线****2.4 通信总线** **3 系统总线的结构****3.1 单总线结构****3.2 双总线结构****3.3 三总线结构** **4 常见的总线…

TextDiffuser: Diffusion Models as Text Painters

TextDiffuser: Diffusion Models as Text Painters (Paper reading) Jingye Chen, HKUST, HK, arXiv2023, Cited: 0, Code, Paper 1. 前言 扩散模型因其出色的生成能力而受到越来越多的关注&#xff0c;但目前在生成准确连贯的文本方面仍存在困难。为了解决这个问题&#xf…

chatgpt赋能python:Python怎么进行302跳转以提高SEO

Python怎么进行302跳转以提高SEO 在进行搜索引擎优化时&#xff0c;重点是提高网站的排名和流量。其中一个关键的因素就是网页的重定向。在Python中&#xff0c;使用302重定向可以为您的网页提供更好的SEO效果。 什么是302跳转&#xff1f; 302跳转指的是HTTP状态码302 Foun…

chatgpt赋能python:Python教程:如何使用Python在U盘上新建文件?

Python教程&#xff1a;如何使用Python在U盘上新建文件&#xff1f; 如果您是一名经验丰富的Python开发人员&#xff0c;那么您可能已经使用Python进行过很多任务。但是&#xff0c;您是否曾经问过自己如何在U盘上使用Python来新建文件&#xff1f;这篇文章将带您逐步了解如何…

chatgpt赋能python:Python中如何使用正弦函数进行数学计算

Python中如何使用正弦函数进行数学计算 正弦函数是数学中经常使用的一种三角函数&#xff0c;可用于测量角度和距离等。Python是一种可以跨平台使用的高级编程语言&#xff0c;它具有许多内置函数来进行数学计算。在Python中使用正弦函数&#xff0c;可以通过输入角度或弧度来…