12-LINUX--进程间的通信

进程间通信:采用IPC机制(进程间的用户空间相互独立,内核空间共享),有管道,信号量,共享内存,消息队列,套接字。

一.管道

        管道可以用来在两个进程之间传递数据,如: ps -ef | grep “bash”, 其中‘|’就是管
道,其作用就是将 ps 命令的结果写入管道文件,然后 grep 再从管道文件中读出该数据进行
过滤。

1.1有名管道

        有名管道可以在任意两个进程之间通信
有名管道的创建:
        ◼ 命令创建: mkfifo FIFO
        ◼ 系统调用创建
#include <sys/types.h>
 #include <sys/stat.h>
 //filename 是管道名 mode 是创建的文件访问权限
 int mkfifo(const char *filename, mode_t mode);

a.c代码

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#include<fcntl.h>int main()
{int fd = open("./fifo",O_WRONLY);if(fd ==-1){exit(1);}printf("fd=%d\n",fd);while(1){printf("intput:\n");char buff[128] ={0};fgets(buff,128,stdin);if(strncmp(buff,"end",3) ==0){break;}write(fd,buff,strlen(buff));}close(fd);
}

b.c代码

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#include<fcntl.h>int main()
{int fd = open("./fifo",O_RDONLY);printf("fd=%d\n",fd);if(fd ==-1){exit(1);}while(1){char buff[128];int n=read(fd,buff,127);if(n==0){break;}printf("buff=%s\n",buff);}close(0);exit(0);
}

运行:

1.2无名管道

无名管道主要应用于父子进程间的通信。
无名管道的创建:
1. #include <unistd.h>
2. /*
3. pipe()成功返回 0,失败返回-1
4. fds[0]是管道读端的描述符
5. fds[1]是管道写端的描述符
6. */
7. int pipe(int fds[2]);
#include<stdio.h>
#include<string.h>
#include<unistd.h>
#include<stdlib.h>
//无名管到
int main()
{int fd[2];//fd[0] r  fd[1]  wif(pipe(fd) == -1){exit(1);}write(fd[1],"hello",5);char buff[128] ={0};read(fd[0],buff,127);printf("%s\n",buff);close(fd[0]);close(fd[1]);exit(0);
}

无名管道父子进程间的通信:

#include<stdio.h>
#include<string.h>
#include<unistd.h>
#include<stdlib.h>int main()
{int fd[2];//fd[0] r  fd[1]  wif(pipe(fd) == -1){exit(1);}pid_t pid =fork();if(pid ==-1){exit(1);}if(pid==0){close(fd[1]);while(1){char buff[128]={0};//read(fd[0],buff,127);if(read(fd[0],buff,127) == 0){//printf("child read:%s\n",buff);break;}printf("chlid read:%s\n",buff);}close(fd[0]);}else{close(fd[0]);while(1){printf("input: ");char buff[128] ={0};fgets(buff,128,stdin);if(strncmp(buff,"end",3)==0){break;}write(fd[1],buff,strlen(buff));}close(fd[1]);}exit(0);
}

1.3管道的特点

无论有名还是无名,写入管道的数据都在内存中
管道是一种半双工通信方式(通信方式有单工、半双工、全双工)
有名和无名管道的区别:有名可以在任意进程间使用,而无名主要在父子进程间

1.4管道的实现

二.信号量

由于父子进程间无法确定谁先谁后,所以运行结果会有顺序错乱的情况

提出使用信号量管理,使得父子进程间的通信变得有序

1.信号量

        信号量是一个特殊的变量,一般取正数值。它的值代表允许访问的资源数目,获取资源
时,需要对信号量的值进行原子减一,该操作被称为 P 操作。当信号量值为 0 时,代表没有
资源可用,P 操作会阻塞。释放资源时,需要对信号量的值进行原子加一,该操作被称为 V
操作。信号量主要用来同步进程。信号量的值如果只取 0,1,将其称为二值信号量。如果信
号量的值大于 1,则称之为计数信号量。
         临界资源:同一时刻,只允许被一个进程或线程访问的资源
        临界区:访问临界资源的代码段

2.信号量的使用

操作信号量的接口介绍:
 #include <sys/sem.h>#include <sys/types.h>#include <sys/ipc.h>/*semget()创建或者获取已存在的信号量semget()成功返回信号量的 ID, 失败返回-1key:两个进程使用相同的 key 值,就可以使用同一个信号量nsems:内核维护的是一个信号量集,在新建信号量时,其指定信号量集中信号
量的个数semflg 可选: IPC_CREAT IPC_EXCL*/int semget(key_t key, int nsems, int semflg);/*semop()对信号量进行改变,做 P 操作或者 V 操作semop()成功返回 0,失败返回-1struct sembuf{unsigned short sem_num; //指定信号量集中的信号量下标short sem_op; //其值为-1,代表 P 操作,其值为 1,代表 V 操作short sem_flg; //SEM_UNDO};*/int semop(int semid, struct sembuf *sops, unsigned nsops);/*semctl()控制信号量semctl()成功返回 0,失败返回-1cmd 选项: SETVAL IPC_RMIDunion semun{int val;
struct semid_ds *buf;unsigned short *array;struct seminfo *_buf;};*/
int semctl(int semid, int semnum, int cmd, ...);
例题:进程 a 和进程 b 模拟访问打印机,进程 a 输出第一个字符‘a’表示开始使用打印
机,输出第二个字符‘a’表示结束使用,b 进程操作与 a 进程相同。(由于打印机同一时刻
只能被一个进程使用,所以输出结果不应该出现 abab),如图所示:

封装信号量的接口:

          sem.h 的代码如下:
#include<stdio.h>
#include<string.h>
#include<unistd.h>
#include<stdlib.h>
#include<sys/sem.h>union semun
{int val;
};
void sem_init();
void sem_p();
void sem_v();
void sem_destroy();
sem.c 的代码如下:
#include "sem.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,IPC_CREAT|0600);//创建失败,说明已有,获取if(semid == -1){printf("semget err\n");return;}}else//创建成功,初始化{union semun a;a.val =1;if(semctl(semid,0,SETVAL,a) == -1){printf("semcrl setval err\n");}}
}
void sem_p()
{struct sembuf buf;buf.sem_num =0; //信号两的下标,目前只有一个,下标为0buf.sem_op =-1;//pbuf.sem_flg = SEM_UNDO;if(semop(semid,&buf,1) == -1){printf("semop p err\n");}
}
void sem_v()
{struct sembuf buf;buf.sem_num =0; //信号两的下标,目前只有一个,下标为0buf.sem_op =1;//vbuf.sem_flg = SEM_UNDO;if(semop(semid,&buf,1) == -1){printf("semop v err\n");}
}
void sem_destroy()//销毁信号量
{if(semctl(semid,0,IPC_RMID) == -1){printf("semctl destroy err\n");}
}
a.c 的代码如下:
#include<stdio.h>
#include<string.h>
#include<unistd.h>
#include<stdlib.h>
#include<sys/sem.h>
#include"sem.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();n=rand() %3;sleep(n);}
}
//gcc -o a a.c sem.c
//gcc -o b b.c sem.c 

b.c代码:

#include<stdio.h>
#include<string.h>
#include<unistd.h>
#include<stdlib.h>
#include<sys/sem.h>
#include"sem.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();n=rand() %3;sleep(n);}sleep(10);sem_destroy();
}
运行结果如下图所示,输出结果只截了部分:
练习题: 三个进程 a、b、c 分别输入“A”、“B”、“C”,要求输出结果必须是“ABCABCABC…”

3.ipcs/ipcrm 介绍

ipcs 可以查看消息队列、共享内存、信号量的使用情况,使用 ipcrm 可以进行删除操作。

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

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

相关文章

终端工具命令行颜色配置(解决终端工具连上服务器之后,无颜色问题)

本期主题&#xff1a; 讲解使用mobaxterm等终端工具连上服务器&#xff0c;但是命令行没有颜色的问题 目录 1. 问题描述2. 原因解释3.测试 1. 问题描述 使用终端工具&#xff08;Mobaxterm等&#xff09;连上服务器之后&#xff0c;发现终端工具没有颜色&#xff0c;如下图&am…

Python学习从0到1 day25 第二阶段 SQL ② Python操作数据库

少年有梦&#xff0c;不应至于心动&#xff0c;更要付诸行动 —— 24.4.12 pymysql 除了使用图形化工具以外&#xff0c;我们也可以使用编程语言来执行SQL从而操作数据库 在Python中&#xff0c;使用第三方库&#xff1a;pymysql来完成对MySQl数据库的操作 安装 pip install py…

GPT4.5发布了?OpenAI终于发布正式版Turbo,重回AI王座第一

令人惊讶的是&#xff0c;短短三个月内&#xff0c;全球最强AI的称号又一次易主了&#xff01;几个月前&#xff0c;Claude3 Opus的性能全面超过了GPT-4&#xff0c;全球网友纷纷转向Claude3&#xff0c;并分享了他们对Claude3的惊艳体验。然而&#xff0c;OpenAI最近再次展示了…

探索GlusterFS:开源分布式文件系统

目录 引言 一、GlusterFS简介 &#xff08;一&#xff09;基本介绍 &#xff08;二&#xff09;GlusterFS特点 &#xff08;三&#xff09;GlusterFS术语 &#xff08;四&#xff09;GlusterFS工作流程 二、GlusterFs的卷类型 &#xff08;一&#xff09;卷类型 &…

【免安装的MATLAB--MATLAB online】

目录&#xff1a; 前言账号的注册图片处理的示例准备图片脚本函数 总结 前言 在计算机、数学等相关专业中&#xff0c;或多或少都会与MATLAB产生藕断丝连的联系&#xff0c;如果你需要使用MATLAB&#xff0c;但是又不想要安装到自己的电脑上&#xff08;它实在是太大了啊&#…

Linux 系统问题排查常用命令

立刻关机 haltcentos安装yum apt-get install yum查找文件夹 find / - name 需要查找文件名称vi里面 查找字符串 “/”&#xff0c;后面跟要查找的字符串&#xff0c;再按回车。vi将光标定位在该串下一次出现的地方上。键入n跳到该串的下一个出现处&#xff0c;键入N跳到该…

正则表达式 速成

正则表达式的作用 正则表达式&#xff0c;又称规则表达式,&#xff08;Regular Expression&#xff0c;在代码中常简写为regex、regexp或RE&#xff09;&#xff0c;是一种文本模式&#xff0c;包括普通字符&#xff08;例如&#xff0c;a 到 z 之间的字母&#xff09;和特殊字…

c语言中<string.h>的strstr与strtok函数

c语言中string.h的strstr与strtok函数 代码运行结果 代码 #include <stdio.h> #include <string.h>///1.在字符串str1里面,查找第一次出现str2的位置 //char * strstr(const char * str1,const char * str2)///2.sep为分割符,根据分割符来对str进行分割 //char * …

解决Django中的UnicodeDecodeError问题

在使用Django进行Web开发时&#xff0c;有时会遇到一些由于编码不一致引起的问题&#xff0c;特别是在处理文件读写操作时。一个常见的错误是UnicodeDecodeError&#xff0c;其表现为gbk codec cant decode byte 0xa6 in position 9737: illegal multibyte sequence。这个问题通…

【设计模式学习】单例模式和工厂模式

꒵˂͈꒱ write in front ꒰˃͈꒵˂͈꒱ ʕ̯•͡˔•̯᷅ʔ大家好&#xff0c;我是xiaoxie.希望你看完之后,有不足之处请多多谅解&#xff0c;让我们一起共同进步૮₍❀ᴗ͈ . ᴗ͈ აxiaoxieʕ̯•͡˔•̯᷅ʔ—CSDN博客 本文由xiaoxieʕ̯•͡˔•̯᷅ʔ 原创 CSDN 如需转…

【SpringBoot:详解Bean装配】

&#x1f3e1;Java码农探花&#xff1a; &#x1f525; 推荐专栏&#xff1a;<springboot学习> &#x1f6f8;学无止境&#xff0c;不骄不躁&#xff0c;知行合一 文章目录 前言一、IoC容器的简介BeanFactory接口源码二、Bean装配扫描装配探索启动类条件装配自定义Bean总…

版本管理|Git -目前最好的版本管理工具

文章目录 什么是版本为什么需要版本管理Git -目前最好的版本管理工具Git的关键特点和概念初始化Git保存代码改变git addgit commit -m ""git statusgit log branch分支管理git branch & git chekoutHEAD的本质git merge 合并fast forward merge 本地与远程如何解…

【一刷《剑指Offer》】面试题 3:二维数组中的查找

力扣对应题目链接&#xff1a;240. 搜索二维矩阵 II - 力扣&#xff08;LeetCode&#xff09; 核心考点&#xff1a;数组相关&#xff0c;特性观察&#xff0c;时间复杂度把握。 一、《剑指Offer》对应内容 二、分析题目 正常查找的过程本质就是排除的过程&#xff0c;谁排除…

【YOLOv9】完胜V8的SOTA模型Yolov9(论文阅读笔记)

官方论文地址&#xff1a; 论文地址点击即可跳转 官方代码地址&#xff1a; GitCode - 开发者的代码家园 官方代码地址点击即可跳转 1 总述 当输入数据经过各层的特征提取和变换的时候&#xff0c;都会丢失一定的信息。针对这一问题&#xff1a; 论文中提出的可编程梯度信息…

免费的 ChatGPT 网站(六个)

&#x1f525;博客主页&#xff1a; 小羊失眠啦. &#x1f3a5;系列专栏&#xff1a;《C语言》 《数据结构》 《C》 《Linux》 《Cpolar》 ❤️感谢大家点赞&#x1f44d;收藏⭐评论✍️ 文章目录 一、insCode二、讯飞星火三、豆包四、文心一言五、通义千问六、360智脑 现在智能…

【漏洞复现】WordPress LayerSlider插件SQL注入漏洞复现

声明&#xff1a;亲爱的读者&#xff0c;我们诚挚地提醒您&#xff0c;Aniya网络安全的技术文章仅供个人研究学习参考。任何因传播或利用本实验室提供的信息而造成的直接或间接后果及损失&#xff0c;均由使用者自行承担责任。Aniya网络安全及作者对此概不负责。如有侵权&#…

C数据结构:双向链表(带头循环)

前言 链表分多种&#xff0c;分别为 不带头不循环单向链表、不带头循环单向链表、带头循环单向链表、带头不循环单向链表 不带头不循环双向链表、不带头循环双向链表、带头循环双向链表、带头不循环双向链表 一共八种 在前一篇博客中完成的单链表即为不带头不循环单向链表…

杰发科技AC7840——CAN通信简介(5)_可变波特率设置

0. 简介 设置可变波特率时候&#xff0c;遇到2个坑&#xff0c;在此记录下来 使用该函数即可 can_time_segment_t bitrate2 s_canBitrate[CAN_BITRATE_250K]; CAN_DRV_SetBitrate(instance, &bitrate2); 1. 波特率指针注意不要空 查看设置波特率的接口&#xff0c;发现…

吉他弹唱谱怎么制作 Guitar Pro 怎么写弹简谱 Guitar Pro8.02简谱

学习如何制作吉他弹唱谱是提升音乐创作和表现能力的重要一环。借助专业的软件工具如Guitar Pro&#xff0c;可以轻松地将音乐创意转化为可视化的乐谱&#xff0c;使演奏和分享变得更加便捷和高效。下面我们来看看吉他弹唱谱怎么制作&#xff0c;Guitar Pro 怎么写弹简谱的相关内…

Llama 3下月正式发布,继续开源!

4月10日&#xff0c;Techcrunch消息&#xff0c;Meta在本周伦敦举办的一场活动中确定&#xff0c;下个月将正式发布Llama 3并且继续开源。 Meta全球事务总裁Nick Clegg表示&#xff0c;我们希望在下个月&#xff0c;甚至更短的时间内&#xff0c;正式推出新一代基础模型Llama …