首页 > 运维 > linux运维 > 正文

【Linux】进程间通信——匿名管道

絕刀狂花
发布: 2025-06-19 15:52:20
原创
172人浏览过
  1. 进程间通信的目的包括数据传输、资源共享、通知事件和进程控制。数据传输是指一个进程需要将数据发送给另一个进程;资源共享是指多个进程共享相同的资源;通知事件是指一个进程需要向另一个或一组进程发送消息,告知发生了某种事件,如进程终止时通知父进程;进程控制是指某些进程希望完全控制另一个进程的执行,如Debug进程希望能够拦截另一个进程的所有陷入和异常,并及时了解其状态变化。

?由于进程具有独立性,不同进程间如何通信呢?进程间通信首先需要让不同的进程看到同一份资源(某种形式的内存空间)。由于进程具有独立性的特性,一个进程不能在另一个进程中操作某种资源,因此该资源的提供者不能是进程,只能是操作系统,这也是进程间通信的核心。

【Linux】进程间通信——匿名管道 进程间通信有两类通信方案——本地通信和网络通信;本地通信指的是在同一台主机同一个操作系统下,不同进程间的通信;本文主要讨论本地通信,网络通信将在后续学习。

  1. Linux进程间通信可以分为以下几种分类:

匿名管道(Pipe):管道是一种半双工的通信机制,可以在同一个进程中的两个文件描述符之间传递数据。 命名管道(Named Pipe):命名管道也是一种半双工的通信机制,但可以在不同进程之间进行通信。 信号(Signal):信号是一种在进程之间传递简单消息的机制,主要用于进程之间的通知和同步。 消息队列(Message Queue):消息队列是一种通过消息传递进行通信的机制,可以在不同进程之间传递消息。 共享内存(Shared Memory):共享内存是一种进程间通信的高效机制,多个进程可以通过映射同一块内存区域来实现数据的共享。 信号量(Semaphore):信号量是一种用于进程之间同步和互斥的机制,可以用来控制对共享资源的访问。 套接字(Socket):套接字是一种可以在不同主机之间进行进程间通信的机制,可以实现分布式系统间的通信。 文件锁(File Lock):文件锁是一种用于进程之间同步和互斥的机制,可以通过锁定文件来控制对共享资源的访问。 根据具体的业务需求选择适合的进程间通信方式,每种通信方式都有其特点和适用场景。

  1. 管道是一种最简单的进程间通信方式,可以通过创建一个管道文件来实现两个进程之间的通信。读进程从管道中读取数据,写进程向管道中写入数据。管道只能在具有父子关系的进程之间使用。

父进程创建子进程后,子进程会拷贝父进程的task_struct,同样父进程在创建子进程之前打开了一个文件,子进程也会拷贝该文件的struct file,此时两个进程就指向同一个操作系统提供给该文件的内核缓冲区,所以就可以通过该文件的内核缓冲区进行通信了:

【Linux】进程间通信——匿名管道 管道分为匿名管道pipe和命名管道。

  1. 在Linux中,匿名管道(anonymous pipe)是一种常用的进程间通信机制。它的原理与上图类似,是通过pipe系统调用来创建一个管道文件,该文件与上图文件不同,没有inode,也不需要写入磁盘,仅仅用来给父子进程间进行通信,可以说是一次性使用的,没有名字,所以称为匿名管道。

创建匿名管道的思路如下:

父进程调用系统调用创建管道:【Linux】进程间通信——匿名管道父进程创建子进程:【Linux】进程间通信——匿名管道如果父进程写入,子进程读取,那么就将父进程读取端关闭,子进程写入端关闭;如果父进程读取,子进程写入,那么就反之:【Linux】进程间通信——匿名管道【Linux】进程间通信——匿名管道管道的通信是单向的,即父进程或子进程不能对一个管道同时读和写,只能选择一个,父进程读,子进程就写;子进程读,父进程就写。

在Linux系统中,可以使用以下系统调用接口创建匿名管道:

#include <unistd.h>
int pipe(int pipefd[2]);
登录后复制

该函数会创建一个管道,并将相应的读取和写入文件描述符存储在pipefd数组中。pipefd[0]表示读取端文件描述符,pipefd[1]表示写入端文件描述符。

使用示例:

#include <unistd.h>
#include <stdio.h>
int main() {
    int pipefd[2];
    int ret = pipe(pipefd);
<pre class="brush:php;toolbar:false">if (ret == -1) {
    perror("pipe");
    return 1;
}

printf("读取端文件描述符:%d\n", pipefd[0]);
printf("写入端文件描述符:%d\n", pipefd[1]);

return 0;
登录后复制

}

运行以上程序,会输出管道的读取和写入端文件描述符。

以下是一个通过匿名管道简单实现进程间通信的代码:

#include<iostream></p><h1>include<string></h1><h1>include<unistd.h></h1><h1>include <sys></h1><h1>include <sys></h1><h1>include <stdlib.h></h1><p>//子进程写,父进程读
int main(){
//1.创建管道
int pipefd[2];
int n = pipe(pipefd);
if(n == -1)
{
std::cerr << "pipe error" << std::endl;
exit(1);
}
//2.创建子进程
pid_t pid = fork();
if(pid < 0)
{
std::cerr << "fork error" << std::endl;
exit(1);
}
else if(pid == 0)
{
//子进程
close(pipefd[0]); //关闭读取端
std::string message = "Hello from child!";
write(pipefd[1], message.c_str(), message.size());
close(pipefd[1]); //关闭写入端
exit(0);
}
else
{
//父进程
close(pipefd[1]); //关闭写入端
char buffer[1024];
int count = read(pipefd[0], buffer, sizeof(buffer) - 1);
if(count > 0)
{
buffer[count] = 0;
std::cout << "Message from child: " << buffer << std::endl;
}
close(pipefd[0]); //关闭读取端
}
return 0;
}
登录后复制

将该代码编译为可执行文件后运行结果如下:

【Linux】进程间通信——匿名管道在进程间通信时,可能会出现以下场景:

管道为空,read会阻塞管道为满,write会阻塞管道写端关闭,读端最终会读到0,表示已经读到文件结尾管道读端关闭,操作系统会直接杀掉写入的进程匿名管道特性:

面向字节流 只能通过具有血缘关系比如父子/兄弟的进程使用,常用于父子进程间通信 文件的生命周期随进程,管道也是 管道通信是单向的管道自带同步互斥等机制,也就是说管道在写的时候不能读取,读的时候不能写入

以上就是【Linux】进程间通信——匿名管道的详细内容,更多请关注php中文网其它相关文章!

最佳 Windows 性能的顶级免费优化软件
最佳 Windows 性能的顶级免费优化软件

每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。

下载
来源:php中文网
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
最新问题
开源免费商场系统广告
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习
PHP中文网抖音号
发现有趣的

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号