linux 进程间通信--systemV 信号量 实例

2024-02-12 04:18

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

1:代码

#include <stdio.h>
#include <sys/types.h>
#include <sys/sem.h>
#include <errno.h>
#include <stdlib.h>
#include <signal.h>
#define MAX_SEMAPHORES  3
union semun
{int val;                   			/* value for SETVAL */struct semid_ds *buf;       		/* buffer for IPC_STAT, IPC_SET */unsigned short int *array;  		/* array for GETALL, SETALL */struct seminfo *__buf;      		/* buffer for IPC_INFO */
};
static int set_semvalue(int sem_id,int semIndex,int semValue)
{union semun sem_union;int value;sem_union.val = semValue;if (semctl(sem_id, semIndex, SETVAL, sem_union) == -1){return(0);}printf("set value success,");printf("init value is %d\n",get_semvalue(sem_id,semIndex));return(1);
}int get_semvalue(int sem_id,int semIndex)
{int res;if((res=semctl(sem_id, semIndex, GETVAL)) == -1){perror("semctl");exit(EXIT_FAILURE);}return res;
}static int semaphore_v(int sem_id,int semIndex)
{struct sembuf sem_b;sem_b.sem_num = semIndex;sem_b.sem_op = 1; /* V() *///sem_b.sem_flg = SEM_UNDO;sem_b.sem_flg=IPC_NOWAIT; //0if (semop(sem_id, &sem_b, 1) == -1){perror("semop");return(0);}return(1);
}static int semaphore_p(int sem_id,int semIndex)
{struct sembuf sem_b;sem_b.sem_num = semIndex;sem_b.sem_op = -1; /* V() *///sem_b.sem_flg = SEM_UNDO;sem_b.sem_flg=IPC_NOWAIT;//0if (semop(sem_id, &sem_b, 1) == -1){perror("semop");return(0);}return(1);
}
void signalHandler(int sig)
{printf("child process exit\n");exit(EXIT_SUCCESS);
}
void semphorePV()
{pid_t childPid;int i;int value;key_t key;int status;int chlid_sem_id,parent_sem_id,semIndex=0,semValue=MAX_SEMAPHORES;if((childPid=fork())==-1){perror("fork");exit(EXIT_FAILURE);}else if(childPid==0){
#if 1struct sigaction sa;sa.sa_handler = signalHandler;sa.sa_flags = 0;	/* Interrupt system calls */sigemptyset(&sa.sa_mask);sigaction(SIGINT, &sa, NULL);sigaction(SIGQUIT, &sa, NULL);
#endifif((chlid_sem_id=semget((key_t)123456,1,IPC_CREAT|0770))==-1){perror("semget");exit(EXIT_FAILURE);}if (!set_semvalue(chlid_sem_id,semIndex,semValue)){fprintf(stderr, "Failed to initialize semaphore\n");exit(EXIT_FAILURE);}value=get_semvalue(chlid_sem_id,semIndex);printf("this is child,the current value is %d\n",value);if(!semaphore_v(chlid_sem_id,semIndex)){fprintf(stderr, "Failed to v operator\n");exit(EXIT_FAILURE);}value=get_semvalue(chlid_sem_id,semIndex);printf("child V operator,the current value is %d\n",value);printf("--------------------------------------------------\n");while(1){if(!semaphore_v(chlid_sem_id,semIndex)){fprintf(stderr, "Failed to v operator\n");exit(EXIT_FAILURE);}value=get_semvalue(chlid_sem_id,semIndex);printf("child V operator,the current value is %d\n",value);sleep(2);}printf("child exit success\n");exit(EXIT_SUCCESS);}else	//parent{sleep(1);if((parent_sem_id=semget((key_t)123456,1,IPC_CREAT|0770))==-1){perror("semget");exit(EXIT_FAILURE);}value=get_semvalue(parent_sem_id,semIndex);printf("this is parent ,the current value is %d\n",value);sleep(1);if(!semaphore_p(parent_sem_id,semIndex)){fprintf(stderr, "Failed to v operator\n");exit(EXIT_FAILURE);}printf("parent P operator,the current value is %d\n",value);printf("################################################################\n");while(1){if(!semaphore_p(parent_sem_id,semIndex)){fprintf(stderr, "Failed to v operator\n");break;}else{value=get_semvalue(parent_sem_id,semIndex);printf("parent P operator,the current value is %d\n",value);}sleep(1);}kill(childPid,SIGINT);sleep(2);if(semctl(parent_sem_id,0, IPC_RMID,(struct msquid_ds*)0)==-1){perror("semctl");exit(EXIT_FAILURE);}else{printf("the parent remove the sem\n");}return 0;}
}
int main(int argc,char *argv)
{semFunTest(argc,argv);semphorePV();
}int semFunTest(int argc,char *argv[]){int i, ret, semid;unsigned short sem_write_array[MAX_SEMAPHORES];unsigned short sem_read_array[MAX_SEMAPHORES];union semun arg;if((semid = semget( IPC_PRIVATE, MAX_SEMAPHORES,IPC_CREAT | 0666 )) == -1){perror("semget");exit(EXIT_FAILURE);}/* Initialize the sem_array */for (i = 0 ; i < MAX_SEMAPHORES ; i++ ){sem_write_array[i] = (unsigned short)(i+1);}/* Update the arg union with the sem_array address */arg.array = sem_write_array;/* Set the values of the semaphore-array */if((ret = semctl( semid, 0, SETALL, arg)) == -1){perror("SETALL failed\n");}/* Update the arg union with another array for read */arg.array = sem_read_array;/* Read the values of the semaphore array */if((ret = semctl( semid, 0, GETALL, arg)) == -1){printf("GETALL failed (%d)\n", errno);}/* print the sem_read_array */for ( i = 0 ; i < MAX_SEMAPHORES ; i++ ){printf("Semaphore %d, value %d\n", i, sem_read_array[i] );}printf("************************************************\n");/* Use GETVAL in a similar manner */for ( i = 0 ; i < MAX_SEMAPHORES ; i++ ){ret = semctl( semid, i, GETVAL );printf("Semaphore %d, value %d\n", i, ret );}/* Delete the semaphore */if(semctl(semid,0, IPC_RMID,(struct msquid_ds*)0)==-1){perror("semctl");exit(EXIT_FAILURE);}else{printf("remove the sem\n");}return 0;
}


2:执行结果




代码:

这篇关于linux 进程间通信--systemV 信号量 实例的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



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

相关文章

怎样通过分析GC日志来定位Java进程的内存问题

《怎样通过分析GC日志来定位Java进程的内存问题》:本文主要介绍怎样通过分析GC日志来定位Java进程的内存问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、GC 日志基础配置1. 启用详细 GC 日志2. 不同收集器的日志格式二、关键指标与分析维度1.

Java进程异常故障定位及排查过程

《Java进程异常故障定位及排查过程》:本文主要介绍Java进程异常故障定位及排查过程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、故障发现与初步判断1. 监控系统告警2. 日志初步分析二、核心排查工具与步骤1. 进程状态检查2. CPU 飙升问题3. 内存

Linux中压缩、网络传输与系统监控工具的使用完整指南

《Linux中压缩、网络传输与系统监控工具的使用完整指南》在Linux系统管理中,压缩与传输工具是数据备份和远程协作的桥梁,而系统监控工具则是保障服务器稳定运行的眼睛,下面小编就来和大家详细介绍一下它... 目录引言一、压缩与解压:数据存储与传输的优化核心1. zip/unzip:通用压缩格式的便捷操作2.

Linux中SSH服务配置的全面指南

《Linux中SSH服务配置的全面指南》作为网络安全工程师,SSH(SecureShell)服务的安全配置是我们日常工作中不可忽视的重要环节,本文将从基础配置到高级安全加固,全面解析SSH服务的各项参... 目录概述基础配置详解端口与监听设置主机密钥配置认证机制强化禁用密码认证禁止root直接登录实现双因素

java向微信服务号发送消息的完整步骤实例

《java向微信服务号发送消息的完整步骤实例》:本文主要介绍java向微信服务号发送消息的相关资料,包括申请测试号获取appID/appsecret、关注公众号获取openID、配置消息模板及代码... 目录步骤1. 申请测试系统2. 公众号账号信息3. 关注测试号二维码4. 消息模板接口5. Java测试

MySQL数据库的内嵌函数和联合查询实例代码

《MySQL数据库的内嵌函数和联合查询实例代码》联合查询是一种将多个查询结果组合在一起的方法,通常使用UNION、UNIONALL、INTERSECT和EXCEPT关键字,下面:本文主要介绍MyS... 目录一.数据库的内嵌函数1.1聚合函数COUNT([DISTINCT] expr)SUM([DISTIN

在Linux终端中统计非二进制文件行数的实现方法

《在Linux终端中统计非二进制文件行数的实现方法》在Linux系统中,有时需要统计非二进制文件(如CSV、TXT文件)的行数,而不希望手动打开文件进行查看,例如,在处理大型日志文件、数据文件时,了解... 目录在linux终端中统计非二进制文件的行数技术背景实现步骤1. 使用wc命令2. 使用grep命令

Linux如何快速检查服务器的硬件配置和性能指标

《Linux如何快速检查服务器的硬件配置和性能指标》在运维和开发工作中,我们经常需要快速检查Linux服务器的硬件配置和性能指标,本文将以CentOS为例,介绍如何通过命令行快速获取这些关键信息,... 目录引言一、查询CPU核心数编程(几C?)1. 使用 nproc(最简单)2. 使用 lscpu(详细信

linux重启命令有哪些? 7个实用的Linux系统重启命令汇总

《linux重启命令有哪些?7个实用的Linux系统重启命令汇总》Linux系统提供了多种重启命令,常用的包括shutdown-r、reboot、init6等,不同命令适用于不同场景,本文将详细... 在管理和维护 linux 服务器时,完成系统更新、故障排查或日常维护后,重启系统往往是必不可少的步骤。本文

基于Linux的ffmpeg python的关键帧抽取

《基于Linux的ffmpegpython的关键帧抽取》本文主要介绍了基于Linux的ffmpegpython的关键帧抽取,实现以按帧或时间间隔抽取关键帧,文中通过示例代码介绍的非常详细,对大家的学... 目录1.FFmpeg的环境配置1) 创建一个虚拟环境envjavascript2) ffmpeg-py