38、IO进程线程/共享内存、信号灯集实现进程间同步通信20240226

本文主要是介绍38、IO进程线程/共享内存、信号灯集实现进程间同步通信20240226,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一、创建共享内存、和信号灯集实现两个进程间同步通信(进程1先发送,进程2后接收,待2接收完成后,1才能继续发送(用信号灯集实现同步机制,有顺序的先后执行))。

代码:

1信号灯集封装函数头文件:sem.h

#ifndef _SEM_H__
#define _SEM_H__//创建或打开信号灯集:参数为要申请的信号灯集包含的灯的个数,返回信号灯集id
int open_sem(int semcount);//进行申请资源操作:参数为要申请的信号灯集id,以及要申请灯的编号
int P(int semid,int semno);//释放资源操作:参数为要释放的信号灯集id,以及要释放灯的编号
int V(int semid,int semno);//删除信号灯集:参数为要删除的信号灯集id
int del_sem(int semid);#endif

2信号灯集创建、初始化、申请、释放、删除操作

#include<myhead.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) */
};int init_semno(int semid,int semno)
{union semun buf;printf("请输入要给编号为%d的灯设置的值:",semno);scanf("%d",&buf.val);getchar();//调用控制函数完成初始化if(semctl(semid,semno,SETVAL,buf)==-1){perror("semctl error");return -1;}return 0;
}
//创建或打开信号灯集:参数为要申请的信号灯集包含的灯的个数,返回信号灯集id
int open_sem(int semcount)
{key_t key=-1;if((key=ftok("/",'s'))==-1){perror("ftok error");return -1;}int semid=-1;//根据key值创建信号灯集if((semid=semget(key,semcount,IPC_CREAT|IPC_EXCL|0664))==-1){if(errno==EEXIST)//如果文件已经存在则直接打开返回semid{semid=semget(key,semcount,IPC_CREAT|0664);return semid;}perror("semget error");return -1;}for(int i=0;i<semcount;i++)//首次打开需要初始化信号灯集{init_semno(semid,i);//对编号为i的灯进行初始化}return semid;
}//进行申请资源操作:参数为要申请的信号灯集id,以及要申请灯的编号
int P(int semid,int semno)
{struct sembuf buf;buf.sem_num=semno;buf.sem_op=-1;buf.sem_flg=1;if(semop(semid,&buf,1)==-1){perror("semop error");return -1;}return 0;
}//释放资源操作:参数为要释放的信号灯集id,以及要释放灯的编号
int V(int semid,int semno)
{	struct sembuf buf;buf.sem_num=semno;buf.sem_op=1;buf.sem_flg=1;if(semop(semid,&buf,1)==-1){perror("semop error");return -1;}return 0;
}//删除信号灯集:参数为要删除的信号灯集id
int del_sem(int semid)
{if(semctl(semid,0,IPC_RMID)==-1){perror("delete error");return -1;}
}

3负责发送信息的进程(使用共享内存)

#include<myhead.h>
#include"sem.h"
#define PAGE_SIZE 4096
int main(int argc, const char *argv[])
{int semid=open_sem(2);//创建信号灯集key_t key=-1;//创建key值if((key=ftok("/",'m'))==-1){perror("ftok error");return -1;}int shmid=-1;//根据key创建共享内存返回共享内存idif((shmid=shmget(key,PAGE_SIZE,IPC_CREAT|0664))==-1){perror("shmget error");return -1;}char *addr=shmat(shmid,NULL,0);//根据shmid将共享内存映射到用户空间if(addr==(void*)-1){perror("shmat error");return -1;}//使用共享内存写入操作while(1){//申请0号灯资源P(semid,0);printf("请输入>>>");fgets(addr,PAGE_SIZE,stdin);addr[strlen(addr)-1]=0;printf("发送成功 \n");//释放1号灯资源V(semid,1);if(strcmp(addr,"quit")==0)break;}//取消映射if(shmdt(addr)==-1){perror("shmdt error");return -1;}//删除共享内存if(shmctl(shmid,IPC_RMID,NULL)==-1){perror("shmctl error");return -1;}return 0;
}

 4负责接收信息的进程

#include<myhead.h>
#include"sem.h"
#define PAGE_SIZE 4096
int main(int argc, const char *argv[])
{//创建信号灯集int semid=open_sem(2);key_t key=-1;//创建key值if((key=ftok("/",'m'))==-1){perror("ftok error");return -1;}int shmid=-1;//根据key创建共享内存返回共享内存idif((shmid=shmget(key,PAGE_SIZE,IPC_CREAT|0664))==-1){perror("shmget error");return -1;}char *addr=shmat(shmid,NULL,0);//根据shmid将共享内存映射到用户空间if(addr==(void*)-1){perror("shmat error");return -1;}//使用共享内存读取操作while(1){//申请1号灯资源P(semid,1);printf("收到数据%s\n",addr);if(strcmp(addr,"quit")==0)break;V(semid,0);//释放0号灯资源}//取消映射if(shmdt(addr)==-1){perror("shmdt error");return -1;}//删除信号灯集del_sem(semid);return 0;
}

运行:

 思维导图:

这篇关于38、IO进程线程/共享内存、信号灯集实现进程间同步通信20240226的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



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

相关文章

Oracle查询优化之高效实现仅查询前10条记录的方法与实践

《Oracle查询优化之高效实现仅查询前10条记录的方法与实践》:本文主要介绍Oracle查询优化之高效实现仅查询前10条记录的相关资料,包括使用ROWNUM、ROW_NUMBER()函数、FET... 目录1. 使用 ROWNUM 查询2. 使用 ROW_NUMBER() 函数3. 使用 FETCH FI

Python脚本实现自动删除C盘临时文件夹

《Python脚本实现自动删除C盘临时文件夹》在日常使用电脑的过程中,临时文件夹往往会积累大量的无用数据,占用宝贵的磁盘空间,下面我们就来看看Python如何通过脚本实现自动删除C盘临时文件夹吧... 目录一、准备工作二、python脚本编写三、脚本解析四、运行脚本五、案例演示六、注意事项七、总结在日常使用

Java实现Excel与HTML互转

《Java实现Excel与HTML互转》Excel是一种电子表格格式,而HTM则是一种用于创建网页的标记语言,虽然两者在用途上存在差异,但有时我们需要将数据从一种格式转换为另一种格式,下面我们就来看看... Excel是一种电子表格格式,广泛用于数据处理和分析,而HTM则是一种用于创建网页的标记语言。虽然两

Java中Springboot集成Kafka实现消息发送和接收功能

《Java中Springboot集成Kafka实现消息发送和接收功能》Kafka是一个高吞吐量的分布式发布-订阅消息系统,主要用于处理大规模数据流,它由生产者、消费者、主题、分区和代理等组件构成,Ka... 目录一、Kafka 简介二、Kafka 功能三、POM依赖四、配置文件五、生产者六、消费者一、Kaf

使用Python实现在Word中添加或删除超链接

《使用Python实现在Word中添加或删除超链接》在Word文档中,超链接是一种将文本或图像连接到其他文档、网页或同一文档中不同部分的功能,本文将为大家介绍一下Python如何实现在Word中添加或... 在Word文档中,超链接是一种将文本或图像连接到其他文档、网页或同一文档中不同部分的功能。通过添加超

windos server2022里的DFS配置的实现

《windosserver2022里的DFS配置的实现》DFS是WindowsServer操作系统提供的一种功能,用于在多台服务器上集中管理共享文件夹和文件的分布式存储解决方案,本文就来介绍一下wi... 目录什么是DFS?优势:应用场景:DFS配置步骤什么是DFS?DFS指的是分布式文件系统(Distr

NFS实现多服务器文件的共享的方法步骤

《NFS实现多服务器文件的共享的方法步骤》NFS允许网络中的计算机之间共享资源,客户端可以透明地读写远端NFS服务器上的文件,本文就来介绍一下NFS实现多服务器文件的共享的方法步骤,感兴趣的可以了解一... 目录一、简介二、部署1、准备1、服务端和客户端:安装nfs-utils2、服务端:创建共享目录3、服

C#使用yield关键字实现提升迭代性能与效率

《C#使用yield关键字实现提升迭代性能与效率》yield关键字在C#中简化了数据迭代的方式,实现了按需生成数据,自动维护迭代状态,本文主要来聊聊如何使用yield关键字实现提升迭代性能与效率,感兴... 目录前言传统迭代和yield迭代方式对比yield延迟加载按需获取数据yield break显式示迭

Python实现高效地读写大型文件

《Python实现高效地读写大型文件》Python如何读写的是大型文件,有没有什么方法来提高效率呢,这篇文章就来和大家聊聊如何在Python中高效地读写大型文件,需要的可以了解下... 目录一、逐行读取大型文件二、分块读取大型文件三、使用 mmap 模块进行内存映射文件操作(适用于大文件)四、使用 pand

python实现pdf转word和excel的示例代码

《python实现pdf转word和excel的示例代码》本文主要介绍了python实现pdf转word和excel的示例代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价... 目录一、引言二、python编程1,PDF转Word2,PDF转Excel三、前端页面效果展示总结一