Linux进程通信

article/2025/9/14 10:50:06

笔者在学习linux的过程中对linux进程通信进行记录学习。现在在 Linux 中使用较多的进程间通信方式主要有以下几种。

(1)管道(Pipe)及有名管道(named pipe):管道可用于具有亲缘关系进程间的通信, 有名管道,除具有管道所具有的功能外,它还允许无亲缘关系进程间的通信。

(2)信号(Signal):信号是在软件层次上对中断机制的一种模拟,它是比较复杂的通信 方式,用于通知接受进程有某事件发生,一个进程收到一个信号与处理器收到一个中断请求 效果上可以说是一样的。

(3)消息队列:消息队列是消息的链接表,包括 Posix 消息队列 systemV 消息队列。它 克服了前两种通信方式中信息量有限的缺点,具有写权限的进程可以向消息队列中按照一定 的规则添加新消息;对消息队列有读权限的进程则可以从消息队列中读取消息。

(4)共享内存:可以说这是最有用的进程间通信方式。它使得多个进程可以访问同一块 内存空间,不同进程可以及时看到对方进程中对共享内存中数据的更新。这种通信方式需要 依靠某种同步机制,如互斥锁和信号量等。

(5)信号量:主要作为进程间以及同一进程不同线程之间的同步手段。

(6)套接字(Socket):这是一种更为一般的进程间通信机制,它可用于不同机器之间的 进程间通信,应用非常广泛。

管道通信

管道主要有无名管道和有名管道。

无名管道:

它只能用于具有亲缘关系的进程之间的通信(也就是父子进程或者兄弟进程之间)。 ·

它是一个半双工的通信模式,具有固定的读端和写端。 ·

管道也可以看成是一种特殊的文件,对于它的读写也可以使用普通的 read、write 等函数。但是它不是普通的文件,并不属于其他任何文件系统,并且只存在于内存中。

管道的创建与关闭

在管道的创建完成后。会有两个文件描述符对该管道得的读和写进行分别描述。fds[0]用于描述读管道,fds[1]用于描述写管道。

在创建管道时需要使用函数pipe。此函数的头文件包含在#include<unistd.h>。

所需头文件 #include

函数原型 int pipe(int fd[2])

函数传入值 fd[2]:管道的两个文件描述符,之后就可以直接操作这两个文件描述符 函数返回值 出错返回-1 , 成功返回0。

/*pipe.c*/
#include <unistd.h> //头文件
#include <errno.h> 
#include <stdio.h> 
#include <stdlib.h> 
int main() 
{ int pipe_fd[2]; //定义函数原型
/*创建一无名管道*/ if(pipe(pipe_fd)<0) //如果pipe创建成功返回0,失败则返回-1,然后输出{ printf("pipe create error\n"); return -1; } else printf("pipe create success\n"); 
/*关闭管道描述符*/ close(pipe_fd[0]); //关闭读通道close(pipe_fd[1]); //关闭写通道
}

父子进程通信

原理如下:父进程先创建一个管道,在使用folk()创建子进程,子承父业。在子进程中也存父进程创建的管道。接下来我们就可以去实现父子进程的

通信了。下图可以看出在管道中分别对应着子进程和分进程的读端和写端,这里要注意。一个进程在读与写中只能选择一项进行,另一项需要使用close()进行给关闭。

 管道读写的实际例子:

/*pipe_rw.c*/ 
#include <unistd.h> 
#include <sys/types.h> 
#include <errno.h> 
#include <stdio.h> 
#include <stdlib.h> 
int main() 
{ int pipe_fd[2]; pid_t pid; char buf_r[100]; //用来暂时存储数据的数组char* p_wbuf; int r_num; 
void *memset(void *s, int ch, size_t n);memset(buf_r,0,sizeof(buf_r)); //将buf_r数组中的内容全部使用0替换
/*函数解释:将s中当前位置后面的n个字节 (typedef unsigned int size_t )用 ch 替换并返回 s 。
memset:作用是在一段内存块中填充某个给定的值,它是对较大的结构体或数组进行清零操作的一种最快方法 。
memset()函数原型是extern void *memset(void *buffer, int c, int count) buffer:为指针或是数组,c:是赋给buffer的值,count:是buffer的长度.*//*创建管道*/ if(pipe(pipe_fd)<0){ printf("pipe create error\n"); return -1; } 
/*创建一子进程*/ if((pid=fork())==0) { printf("\n"); 
/*关闭子进程写描述符,并通过使父进程暂停 2 秒确保父进程已关闭相应的读描述符*/ close(pipe_fd[1]); sleep(2); 
/*子进程读取管道内容*/ if((r_num=read(pipe_fd[0],buf_r,100))>0){ printf("%d numbers read from the pipe is %s\n",r_num,buf_r); } 
/*关闭子进程读描述符*/ close(pipe_fd[0]); exit(0); } 
else if(pid>0) { 
/*/关闭父进程读描述符,并分两次向管道中写入 Hello Pipe*/ close(pipe_fd[0]); if(write(pipe_fd[1],"Hello",5)!= -1) printf("parent write1 success!\n"); if(write(pipe_fd[1]," Pipe",5)!= -1) printf("parent write2 success!\n"); 
/*关闭父进程写描述符*/ close(pipe_fd[1]); sleep(3); 
/*收集子进程退出信息*/ waitpid(pid,NULL,0); exit(0); } 
} 

运行结果为:

[root@(none) 1]# ./pipe_rw2 
parent write1 success! 
parent write2 success! 
10 numbers read from the pipe is Hello Pipe 

管道读写注意:

首先只有在管道的读端存在时向管道中写入数据才有意义。否则,向管道中写入数据的进 程将收到内核传来的 SIFPIPE 信号(通常 Broken pipe 错误)。

· 向管道中写入数据时,linux 将不保证写入的原子性,管道缓冲区一有空闲区域,写进程 就会试图向管道写入数据。如果读进程不读取管道缓冲区中的数据,那么写操作将会一直阻塞。 这句话也很好理解,一个杯子一直装水不放水,杯子就会被装满,在装不进去。·

父子进程在运行时,它们的先后次序并不能保证,因此,在这里为了保证父进程已经 关闭了读描述符,可在子进程中调用 sleep 函数。这里就说明了在进行读写操作时,需要使用延时确保写入完全后在进行读,才能保证数据的完整性。

标准流管道

与 Linux 中文件操作有基于文件流的标准 I/O 操作一样,管道的操作也支持基于文件流 的模式。这种基于文件流的管道主要是用来创建一个连接到另一个进程的管道,这里的“另 一个进程”也就是一个可以进行一定操作的可执行文件,例如,用户执行“cat popen.c”或 者自己编写的程序“hello”等。由于这一类操作很常用,因此标准流管道就将一系列的创建 过程合并到一个函数 popen 中完成。它所完成的工作有以下几步。 · 创建一个管道。 · fork 一个子进程。 · 在父子进程中关闭不需要的文件描述符。 · 执行 exec 函数族调用。 · 执行函数中所指定的命令。 这个函数的使用可以大大减少代码的编写量,但同时也有一些不利之处,例如,它没有 前面管道创建的函数灵活多样,并且用 popen 创建的管道必须使用标准 I/O 函数进行操作, 但不能使用前面的 read、write 一类不带缓冲的 I/O 函数。 与之相对应,关闭用 popen 创建的流管道必须使用函数 pclose 来关闭该管道流。该函数 关闭标准 I/O 流,并等待命令执行结束。

函数格式见下图:

 有名管道

前面只是有关无名管道的一些基础知识。现在进行的是另一个主角。有名管道。

有名管道可以使互不相关的两个进程实现彼此通信。 该管道可以通过路径名来指出,并且在文件系统中是可见的。在建立了管道之后,两个进程 就可以把它当作普通文件一样进行读写操作,使用非常方便。

有名管道的创建可以使用函数 mkfifo(),该函数类似文件中的 open()操作,可以指定管 道的路径和打开的模式。用户还可以在命令行使用“mknod 管道名 p”来创建有名管道。

mkfifo函数使用

 

 

 使用示例:

/*fifo_write.c*/ 
#include <sys/types.h> 
#include <sys/stat.h> 
#include <errno.h> 
#include <fcntl.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#define FIFO "/tmp/myfifo" 
main(int argc,char** argv) 
/*参数为即将写入的字节数*/ 
{ int fd; char w_buf[100]; int nwrite; if(fd== -1) if(errno==ENXIO) printf("open error; no reading process\n"); 
/*打开 FIFO 管道,并设置非阻塞标志*/ fd=open(FIFO_SERVER,O_WRONLY|O_NONBLOCK,0); if(argc==1) printf("Please send something\n"); strcpy(w_buf,argv[1]); 
/*向管道中写入字符串*/ if((nwrite=write(fd,w_buf,100))== -1){ if(errno==EAGAIN) printf("The FIFO has not been read yet.Please try later\n"); } else printf("write %s to the FIFO\n",w_buf); 
} 
/*fifl_read.c*/ 
#include <sys/types.h> 
#include <sys/stat.h> 
#include <errno.h> 
#include <fcntl.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#define FIFO "/tmp/myfifo" 
main(int argc,char** argv) 
{ char buf_r[100]; int fd; 
int nread; 
/*创建有名管道,并设置相应的权限*/ if((mkfifo(FIFO,O_CREAT|O_EXCL)<0)&&(errno!=EEXIST)) printf("cannot create fifoserver\n"); printf("Preparing for reading bytes...\n"); memset(buf_r,0,sizeof(buf_r)); 
/*打开有名管道,并设置非阻塞标志*/ fd=open(FIFO,O_RDONLY|O_NONBLOCK,0); if(fd== -1) { perror("open"); exit(1); } while(1) { memset(buf_r,0,sizeof(buf_r)); if((nread=read(fd,buf_r,100))== -1){ if(errno==EAGAIN) printf("no data yet\n"); } printf("read %s from FIFO\n",buf_r); sleep(1); } pause(); unlink(FIFO); 
}

运行结果:

终端1:

[root@localhost FIFO]# ./read 
Preparing for reading bytes…
read from FIFO 
read from FIFO 
read from FIFO 
read from FIFO 
read from FIFO 
read hello from FIFO 
read from FIFO 
read from FIFO 
read FIFO from FIFO 
read from FIFO 
read from FIFO 
…

终端2:

[root@localhost]# ./write hello 
write hello to the FIFO 
[root@localhost]# ./read FIFO 
write FIFO to the FIFO 


http://chatgpt.dhexx.cn/article/XTZuDb4S.shtml

相关文章

【Linux】进程间通信

目录 1. 进程间通信 1.1. 进程间通信的目的 1.2. 如何实现进程间通信 2. 管道通信 2.1. 匿名管道 2.1.1 创建匿名管道 2.1.2 . 深入理解匿名管道 2.2. 命名管道 2.2.1. 创建命名管道 3. system V 标准进程间通信 3.1. 共享内存 3.1.1. 实现原理 3.1.2. 代码实现 3…

认知智能理论三体论介绍简介

三体论是探索研究宇宙&#xff0c;信息和人类大脑三者关系的理论体系。是认知智能的奠基理论体系之一。宇宙和信息&#xff0c;信息和人类大脑&#xff0c;人类大脑和宇宙&#xff0c;三者之间存在着某种未被完全揭示的奥秘。三体论的核心思想体系就是基于宇宙&#xff0c;信息…

认知智能三大技术体系之类脑模型简介

认知智能三大技术体系之类脑模型简介 类脑模型是认知智能核心三大技术体系之一&#xff0c;类脑结构&#xff0c;功能机制的总称。类脑模型技术体系核心指导思想来自认知智能三大奠基理论&#xff0c;脑科学&#xff0c;心理学&#xff0c;逻辑学&#xff0c;情感学&#xff0c…

认知智能CI和人工智能AI的区别介绍简介

认知智能CI和人工智能AI的区别 人工智能和认知智能都是计算机科学的分支学科之一。人工智能是智能时代的第二个阶段&#xff0c;认知智能是智能时代的第三个阶段。认知智能也并不是智能时代发展的最终阶段&#xff0c;最终阶段应该是通用智能强智能时代。 本文主要就人工智能和…

什么是认知智能?

认知智能是计算机科学的一个分支科学&#xff0c;是智能科学发展的高级阶段&#xff0c;它以人类认知体系为基础&#xff0c;以模仿人类核心能力为目标&#xff0c;以信息的理解、存储、应用为研究方向&#xff0c;以感知信息的深度理解和自然语言信息的深度理解为突破口&#…

认知智能是什么?

认知智能是计算机科学的一个分支科学&#xff0c;是智能科学发展的高级阶段&#xff0c;它以人类认知体系为基础&#xff0c;以模仿人类核心能力为目标&#xff0c;以信息的理解、存储、应用为研究方向&#xff0c;以感知信息的深度理解和自然语言信息的深度理解为突破口&#…

人工智能导论

目录 1.1 人工智能导论 1.2 人工智能应用 1.3 人工智能产业发展 1.4 人工智能发展的成功因素 1.5 人工智能迅速发展的技术领域 1.6人工智能的基础知识 1.1 人工智能导论 人工智能的三个层面&#xff1a; 计算智能&#xff1a;能算能存 感知智能&#xff1a;能听会说&…

如何用AI技术增强企业认知智能?超详细架构解读

认知的高度决定了创造价值的高度。 企业在从创办、发展、竞争、成功到衰亡的全生命周期中&#xff0c;会面临复杂多样的决策场景。 然而&#xff0c;时代演变产生的海量、分散、实时的信息&#xff0c;仅靠人类个体是难以高效、准确地感知、认知和决策的。 因此&#xff0c;企…

深度KWeaver:价值驱动,认知智能走向开源共创

文|智能相对论 作者|叶远风 在底层硬件创新之外&#xff0c;软件创新对提升中国前沿科技竞争力同样重要&#xff0c;这其中&#xff0c;开源的必要性毋庸置疑。但是&#xff0c;在全球范围内开源项目硕果累累的大背景下&#xff0c;中国开源过去的发展却不够快&#xff0c;直…

AI的下一个战场:认知智能的突围

2020-01-20 14:32 导语&#xff1a;AI的下一种可能 “深度学习的钥匙丢在了黑暗角落。”张钹院士不止一次提出这个论点。深度学习方法易受欺骗、易受攻击已经是研究者们达成的共识&#xff0c;追其根本原因&#xff0c;张钹归结为&#xff1a;大家只是在灯亮的方向对模型修修补…

认知智能介绍发展道翰天琼

计算智能、感知智能和认知智能&#xff0c;是探索人工智能道路上的三个台阶。 在计算智能方面&#xff0c;机器早已远远超过人类。而在感知智能方面&#xff0c;机器也已达到可媲美人类的水平。科大讯飞在语音识别错误率上每年相对下降30%以上。在2018年CHiME-5国际多通道语音分…

【干货】认知智能时代:知识图谱实践案例集.pdf(附下载链接)

大家好&#xff0c;我是文文&#xff08;微信号&#xff1a;sscbg2020&#xff09;&#xff0c;今天给大家分享中国电子技术标准化研究院于2021年1月份发布的干货报告《认知智能时代&#xff1a;知识图谱实践案例集.pdf》&#xff0c;关注知识图谱及人工智能伙伴们别错过了&…

肖仰华:知识图谱与认知智能

今天跟大家分享的主题是《知识图谱与认知智能》。 知识图谱自2012年提出至今&#xff0c;发展迅速&#xff0c;如今已经成为人工智能领域的热门问题之一&#xff0c;吸引了来自学术界和工业界的广泛关注&#xff0c;在一系列实际应用中取得了较好的落地效果&#xff0c;产生了巨…

【认知智能】邓志东教授:如何迈向认知智能与通用人工智能

中国金融信息网讯 9月10日-13日&#xff0c;2017世界物联网博览会在无锡召开&#xff0c;清华大学计算机科学与技术系教授邓志东在网易AI公开课上介绍了人工智能现状和复兴原因&#xff0c;及其商业价值和中国人工智能产业发展的优势和短板&#xff0c;以及如何迈向认知智能与通…

智能发展的四个层次:运算智能,感知智能,认知智能,强智能。道翰天琼认知智能。

2016年&#xff0c;人工智能成为产业界和学术界的大热词。年初&#xff0c;李世石与Alpha Go的人机围棋大战吸睛无数&#xff0c;人工智能的话题始料未及地席卷了世界每处。此外&#xff0c;今年也恰逢人工智能学科诞生一甲子&#xff0c;Alpha Go再一次打败人类&#xff0c;受…

知识图谱认知智能理论与实战----------第一章 知识图谱概述

文章目录 一. 什么是知识图谱二. DIKW模型三. 知识图谱技术体系四. 知识图谱辨析I. 知识图谱与自然语言处理II. 知识图谱与图数据库III. 知识图谱与语义网络IV. 知识图谱与搜索引擎 一. 什么是知识图谱 知识图谱&#xff1a;是一种对知识间的关联进行建模的方法&#xff0c;目…

新基建之人工智能认知智能发展新阶段

前言 城市新型基础设施建设是城市化发展的载体&#xff0c;也是城市化发展的需求。当前我国城 镇化进程的发展规模和速度令人瞩目&#xff0c;2019 年我国城镇化率达到 60.6%。然而&#xff0c;与美、日等 发达经济体 82%到 91%的城市化水平仍有较大差距。随着城乡融合战略的推…