信号灯——进程通信——day16

2024-03-06 00:36
文章标签 进程 通信 day16 信号灯

本文主要是介绍信号灯——进程通信——day16,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

今天主要讲一下信号灯,也是有名信号量,一共分为四个步骤:创建、销毁、申请以及释放

首先是创建:

semget int semget(key_t key, int nsems, int semflg);
功能:创建一组信号量
参数:key:IPC对象名nsems:信号量的个数semflg:IPC_CREAT 
返回值:成功返回信号量ID失败返回-1 

销毁

semctl
int semctl(int semid, int semnum, int cmd, ...);
功能:   向信号灯发送命令
参数:semid:信号灯ID号semnum:具体操作信号量的编号cmd:IPC_RMID    删除信号灯SETVAL      设置信号量的值
返回值:成功返回0失败返回-1 初始化:
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) */
};

申请、释放信号量

semop int semop(int semid, struct sembuf *sops, size_t nsops);
功能:对信号量完成操作
参数:semid:信号灯的ID号sops:信号量操作的数组首地址nsops:数组元素个数
返回值:成功返回0 失败返回-1 unsigned short sem_num;  /* semaphore number */        操作信号量的下标short          sem_op;   /* semaphore operation */     具体对信号量的操作(申请:-1  释放:+1short          sem_flg;  /* operation flags */         SEM_UNDO

示例:写个共享内存,一边收,另一边发。

head.h

#ifndef __HEAD_H__
#define __HEAD_H__#include<signal.h>
#include <semaphore.h>
#include<sys/stat.h>
#include<sys/types.h>
#include<sys/wait.h>
#include<pthread.h>
#include<unistd.h>
#include<fcntl.h>
#include<stdio.h>
#include<dirent.h>
#include<string.h>
#include<time.h>
#include<pwd.h>
#include<grp.h>
#include<stdlib.h>
#include<sys/ipc.h>
#include<sys/msg.h>
#include<sys/shm.h>
#include<sys/sem.h>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) */
};extern int init_sem(int semid, int *parray, int len);
extern int sem_p(int semid, int num);
extern int sem_v(int semid, int num);#endif
linux@ub

read.c

#include "head.h"int main(void)
{key_t key;int shmid = 0;int semid = 0;int val[2] = {0,1};char *pshmaddr = NULL;key = ftok(".",'a');if(-1 == key){perror("fail to ftok");return -1;}semid = semget(key,2,IPC_CREAT|0664);if(-1 == semid){perror("fail to semid");return -1;}init_sem(semid,val,2);shmid = shmget(key,4096,IPC_CREAT|0664);if(-1 == shmid){perror("fail to shmget");return -1;}pshmaddr = shmat(shmid,NULL,0);if(NULL == pshmaddr){perror("fail to shmat");return -1;}while(1){sem_p(semid,0);printf("SHMADDR:%s\n",pshmaddr);if(!strcmp(pshmaddr,".quit")){break;}sem_v(semid,1);}shmdt(pshmaddr);shmctl(shmid,IPC_RMID,NULL);return 0;
}

write.c

#include "head.h"int main(void)
{key_t key;int shmid = 0;int semid = 0;int val[2] = {0,1};char *pshmaddr = NULL;key = ftok(".",'a');if(-1 == key){perror("fail to ftok");return -1;}semid = semget(key,2,IPC_CREAT|0664);if(-1 == semid){perror("fail to semid");return -1;}init_sem(semid,val,2);shmid = shmget(key,4096,IPC_CREAT|0664);if(-1 == shmid){perror("fail to shmget");return -1;}pshmaddr = shmat(shmid,NULL,0);if(NULL == pshmaddr){perror("fail to shmat");return -1;}while(1){sem_p(semid,1);gets(pshmaddr);sem_v(semid,0);if(!strcmp(pshmaddr,".quit")){break;}}shmdt(pshmaddr);shmctl(shmid,IPC_RMID,NULL);return 0;
}

sem.c

#include"head.h"int init_sem(int semid,int *parray,int len)
{union semun myun;int i = 0;int ret = 0;for(i = 0;i < len;++i){myun.val = parray[i];ret = semctl(semid,i,SETVAL,myun);if(-1 == ret){perror("fail to semctl");return -1;}}return 0;
}int sem_p(int semid,int num)
{int ret = 0;struct sembuf mybuf;mybuf.sem_num = num;mybuf.sem_op = -1;mybuf.sem_flg = SEM_UNDO;ret = semop(semid,&mybuf,1);if(-1 == ret){perror("fail to semop");return -1;}return 0;
}int sem_v(int semid,int num)
{int ret = 0;struct sembuf mybuf;mybuf.sem_num = num;mybuf.sem_op = +1;mybuf.sem_flg = SEM_UNDO;ret = semop(semid,&mybuf,1);if(-1 == ret){perror("fail to semop");return -1;}return 0;
}

结果:
在这里插入图片描述

这篇关于信号灯——进程通信——day16的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/778316

相关文章

C#如何优雅地取消进程的执行之Cancellation详解

《C#如何优雅地取消进程的执行之Cancellation详解》本文介绍了.NET框架中的取消协作模型,包括CancellationToken的使用、取消请求的发送和接收、以及如何处理取消事件... 目录概述与取消线程相关的类型代码举例操作取消vs对象取消监听并响应取消请求轮询监听通过回调注册进行监听使用Wa

系统架构师考试学习笔记第三篇——架构设计高级知识(20)通信系统架构设计理论与实践

本章知识考点:         第20课时主要学习通信系统架构设计的理论和工作中的实践。根据新版考试大纲,本课时知识点会涉及案例分析题(25分),而在历年考试中,案例题对该部分内容的考查并不多,虽在综合知识选择题目中经常考查,但分值也不高。本课时内容侧重于对知识点的记忆和理解,按照以往的出题规律,通信系统架构设计基础知识点多来源于教材内的基础网络设备、网络架构和教材外最新时事热点技术。本课时知识

[Linux]:进程(下)

✨✨ 欢迎大家来到贝蒂大讲堂✨✨ 🎈🎈养成好习惯,先赞后看哦~🎈🎈 所属专栏:Linux学习 贝蒂的主页:Betty’s blog 1. 进程终止 1.1 进程退出的场景 进程退出只有以下三种情况: 代码运行完毕,结果正确。代码运行完毕,结果不正确。代码异常终止(进程崩溃)。 1.2 进程退出码 在编程中,我们通常认为main函数是代码的入口,但实际上它只是用户级

【STM32】SPI通信-软件与硬件读写SPI

SPI通信-软件与硬件读写SPI 软件SPI一、SPI通信协议1、SPI通信2、硬件电路3、移位示意图4、SPI时序基本单元(1)开始通信和结束通信(2)模式0---用的最多(3)模式1(4)模式2(5)模式3 5、SPI时序(1)写使能(2)指定地址写(3)指定地址读 二、W25Q64模块介绍1、W25Q64简介2、硬件电路3、W25Q64框图4、Flash操作注意事项软件SPI读写W2

vue2 组件通信

props + emits props:用于接收父组件传递给子组件的数据。可以定义期望从父组件接收的数据结构和类型。‘子组件不可更改该数据’emits:用于定义组件可以向父组件发出的事件。这允许父组件监听子组件的事件并作出响应。(比如数据更新) props检查属性 属性名类型描述默认值typeFunction指定 prop 应该是什么类型,如 String, Number, Boolean,

java 进程 返回值

实现 Callable 接口 与 Runnable 相比,Callable 可以有返回值,返回值通过 FutureTask 进行封装。 public class MyCallable implements Callable<Integer> {public Integer call() {return 123;}} public static void main(String[] args

C#关闭指定时间段的Excel进程的方法

private DateTime beforeTime;            //Excel启动之前时间          private DateTime afterTime;               //Excel启动之后时间          //举例          beforeTime = DateTime.Now;          Excel.Applicat

linux中使用rust语言在不同进程之间通信

第一种:使用mmap映射相同文件 fn main() {let pid = std::process::id();println!(

Golang进程权限调度包runtime

关于 runtime 包几个方法: Gosched:让当前线程让出 cpu 以让其它线程运行,它不会挂起当前线程,因此当前线程未来会继续执行GOMAXPROCS:设置最大的可同时使用的 CPU 核数Goexit:退出当前 goroutine(但是defer语句会照常执行)NumGoroutine:返回正在执行和排队的任务总数GOOS:目标操作系统NumCPU:返回当前系统的 CPU 核数量 p

DAY16:什么是慢查询,导致的原因,优化方法 | undo log、redo log、binlog的用处 | MySQL有哪些锁

目录 什么是慢查询,导致的原因,优化方法 undo log、redo log、binlog的用处  MySQL有哪些锁   什么是慢查询,导致的原因,优化方法 数据库查询的执行时间超过指定的超时时间时,就被称为慢查询。 导致的原因: 查询语句比较复杂:查询涉及多个表,包含复杂的连接和子查询,可能导致执行时间较长。查询数据量大:当查询的数据量庞大时,即使查询本身并不复杂,也可能导致