vs2010c 做网站,房产中介 网站模板,南充网站建设略奥科技,涉县全员核酸检测文章目录 引言理解 Linux 进程间通信#xff08;IPC#xff09;基础什么是进程间通信#xff08;IPC#xff09;#xff1f; 管道#xff08;Pipe#xff09;的基本介绍使用场景#xff1a;管道特点#xff1a;管道类型#xff1a;匿名管道命名管道#xff08;FIFOIPC基础什么是进程间通信IPC 管道Pipe的基本介绍使用场景管道特点管道类型匿名管道命名管道FIFO 结论 坚持不懈努力奋斗每一步都是通向成功的征程。在追逐梦想的路上坚定的信念和不屈的意志将成就辉煌的明天。愿你勇敢面对挑战坚定前行绽放出属于自己的光芒。加油✨ ——家驹 引言
《Linux系统编程篇》——基础篇首页传送门 我们学习了forkwaitwaitpidexit以及exec系列函数等但是还是相当局限唯一能够通讯的还是等待子进程结束靠着wait等待中间好像没有办法在传递消息了内存又是独立我怎么能实现呢还是上节说到的丰富自己。提高自己的认知加油吧我们开始学习新的内容进程之间的通讯在技术领域我们称之为IPC。
理解 Linux 进程间通信IPC基础
进程间通信Inter-Process CommunicationIPC 是操作系统中使不同进程交换数据、协同工作的机制。进程间通信广泛用于客户端-服务器应用、多进程应用及系统服务中。Linux 提供了多种 IPC 方式本文将介绍几种主要的 IPC 方法管道、消息队列、共享内存和信号。 什么是进程间通信IPC
在 Linux 中进程是相互独立的每个进程都有独立的内存空间。为了在不同进程之间交换数据操作系统提供了各种 IPC 机制。这些机制可帮助进程完成数据共享、同步、通知和事件处理等任务。
常见的 IPC 方式包括
管道Pipe命名管道FIFO消息队列Message Queue共享内存Shared Memory信号Signal套接字Socket 管道Pipe的基本介绍
管道是最简单的 IPC 方式之一适合在具有亲缘关系的进程如父子进程之间传递数据。管道是单向的数据只能从一端流向另一端。它允许一个进程的输出直接作为另一个进程的输入。管道是一种半双工的通信方式数据只能在一个方向上流动。
我们在没有学习进程通讯的时候我们其实就已经在使用管道了当我们使用命令行|竖线shift\其实就已经使用管道了我们回忆一下。
还记得之前我们使用ps -aux命令的时候吗我们使用了管道(pipe)和grep配合进行了筛选筛选出来了我们想要的数据。
使用场景 进程间通信父子进程之间或者兄弟进程之间进行数据传输。 管道重定向将一个进程的输出重定向到另一个进程的输入。 Shell命令管道通过管道将多个命令连接起来实现数据流的传递。
管道特点 单向通信管道是单向的数据只能从一个端口流向另一个端口。 半双工通信管道可以同时读写但不能同时进行读写操作。 进程间通信管道通常用于实现父子进程或者兄弟进程之间的通信。
管道类型
管道我们分俩种类型一种是有名字的管道命名管道一种是没有名字的管道匿名管道我们来看两者的区别。 匿名管道Anonymous Pipe最常见的管道类型用于在父子进程或者兄弟进程之间进行通信。通过pipe系统调用创建通常是一种临时的通信方式。 命名管道Named PipeFIFO是一种特殊类型的文件可以在不相关的进程间进行通信。通过mkfifo命令或系统调用创建通常用于持久性通信。
看上去只是调用的系统接口不一样我们直接上代码直观的了解一下。
匿名管道
#include unsistd.h
int pipe(int pipefd[2]);用法
使用 pipe() 系统调用创建管道。管道有两个文件描述符一个用于读取另一个用于写入。父进程和子进程可以通过管道实现数据传输。
示例代码
#include stdio.h
#include unistd.h
#include string.hint main() {int fd[2];char buffer[20];// 创建管道if (pipe(fd) -1) {perror(pipe failed);return 1;}if (fork() 0) { // 子进程close(fd[0]); // 关闭读端char message[] Hello from child!;write(fd[1], message, strlen(message) 1); // 写入管道close(fd[1]);} else { // 父进程close(fd[1]); // 关闭写端read(fd[0], buffer, sizeof(buffer)); // 从管道读取printf(Parent received: %s\n, buffer);close(fd[0]);}return 0;
}结果:
父进程创建了一个管道然后通过fork创建了一个子进程父子进程之间通过管道进行通信。子进程向管道中写入一个消息父进程从管道中读取该消息并输出到标准输出。
在代码中子进程关闭了管道的读端fd[0]然后向管道的写端fd[1]写入消息。父进程关闭了管道的写端然后从管道的读端读取消息到buffer中并输出到标准输出。 注意:在子进程中写入消息后父进程才能从管道中读取消息。这保证了父子进程之间的同步通信。
对于管道通信可以看作特殊的文件对于他的读写可以使用writeread函数进程操作但他不是普通文件并不存在于文件系统当中而是存在于内存当中。且数据只能被读取一次 命名管道FIFO
命名管道FIFO是管道的一种但支持无亲缘关系的进程间通信。FIFO 在文件系统中以特殊文件形式存在可以被多个进程打开进行读写操作。
#include sys/types.h
#include sys/stat.h
int mkfifo(const char *pathname, mode_t mode);函数执行成功返回0失败则返回-1俩个参数分别为创建管道的路径及文件名字和权限。 例如mkfifo(./file,0666) 这段表示在当前文件夹目录下创建名字为file的管道文件权限为0666可读可写 文件的权限r 表示可读取w 表示可写入x 表示可执行分别表示为数字为r4w2x1 权限又按用户的不同分为三类User、Group、及Other三类用户的权限。 如对于User用户若拥有rw权限则为426所以0666中的666代表User、Group、及Other的权限分别是666即均为rw权限。 而0666中的0代表不设置特殊的用户id此处还可设为4214代表具有root权限即suid2代表sgid1代表sticky 用法
使用 mkfifo() 或 mknod() 创建 FIFO 文件。进程可以通过文件路径打开 FIFO 文件进行读写。
示例代码
#include stdio.h
#include stdlib.h
#include unistd.h
#include fcntl.hint main() {const char *fifo_path /tmp/my_fifo;// 创建 FIFO 文件mkfifo(fifo_path, 0666);if (fork() 0) { // 子进程int fd open(fifo_path, O_WRONLY);write(fd, Hello from child!, 17);close(fd);} else { // 父进程char buffer[20];int fd open(fifo_path, O_RDONLY);read(fd, buffer, sizeof(buffer));printf(Parent received: %s\n, buffer);close(fd);}return 0;
}绿色部分是因为我的buffer没有初始化所以会有乱码可以加一个memset进行初始化一下就看不到乱码了可以看到我在当前目录创建了一个文件my_fifo,子进程往我们的my_fifo写入了字符串在父进程父进程去读取然后打印了出来。 结论
在管道操作过程中需要注意错误处理如处理管道创建失败、读写数据异常等情况。
对于管道的探索远不止我博客写的这些希望以后学员们可以灵活应用这一通讯技术。通过管道不同进程之间可以方便地进行数据交换和通信实现更复杂的系统功能。