Linux 无名管道

无名管道(unnamed pipe)是一种进程间通信的方式,通常用于父子进程之间的通信。下面是使用无名管道的基本步骤:

pipe 调用的返回值如下:

  • 成功时 :pipe 调用成功时返回 0。
  • 失败时 :如果 pipe 调用失败,返回 -1,并设置 errno 以指示错误原因。errno 可能被设置为以下几种值之一:
    • EBADF:文件描述符不正确。
    • EACCES:没有权限创建管道。
    • EMFILE:进程已经达到了它能够打开的文件描述符的最大数量。
    • ENFILE:系统已经达到了能够打开的文件的最大数量。
    • ENOMEM:没有足够的内核内存资源来创建管道。
  1. 创建一个无名管道:使用 pipe() 函数创建一个无名管道,它会返回两个文件描述符,fd0 用于读取数据,fd1 用于写入数据。
c 复制代码
int fd[2];
pipe(fd);
  1. 创建子进程:使用 fork() 函数创建一个子进程,子进程会继承父进程的文件描述符。
c 复制代码
pid_t pid = fork();
  1. 在父进程中写入数据:如果当前是父进程,则可以使用 fd1 来写入数据到无名管道。
c 复制代码
if (pid > 0) {
    close(fd[0]);  // 关闭读取端
    write(fd[1], data, sizeof(data));
    close(fd[1]);  // 关闭写入端
}
  1. 在子进程中读取数据:如果当前是子进程,则可以使用 fd0 来读取从父进程写入的数据。
c 复制代码
if (pid == 0) {
    close(fd[1]);  // 关闭写入端
    read(fd[0], buffer, sizeof(buffer));
    close(fd[0]);  // 关闭读取端
}

注意事项:

  • 父进程和子进程在使用无名管道时需要关闭不使用的一端,以避免造成不必要的阻塞。
  • 无名管道是一个单向通道,数据只能单向流动,需要双向通信时可以创建两个无名管道。
  • 无名管道只能在具有共同祖先的进程之间使用。
  • 无名管道的大小是有限的,一般为 65536 字节,超过该大小的数据会被截断。

这是一个简单的示例,请根据实际情况进行相应的修改和扩展。

cpp 复制代码
//无名管道(pipe)
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <string.h>
int main(void){
        int fd[2];//两个管道
        char buf[100];//用于存储发送和接收的内容
        if(pipe(fd)<0){//管道失败的话
                perror( "pipe");
                exit(1);
        }
        printf("无名管道开始\n");
        pid_t fork_ret=fork();
        if(fork_ret<0){
                perror("fork()");
                return -1; 
        }else if(fork_ret==0){
                while(1){
                        bzero(buf,sizeof(buf));
                        printf("\n大好儿:PID:%d  PPID:%d\n\n",getpid(),getppid());
                        read(fd[0],buf,sizeof(buf));
                        printf("呀 是 爹!!发来的:%s \n",buf);
                        if( strncmp(buf,"quit",4) == 0){ 
                                break;
                        }
                }
        }else{
                while(1){
                        bzero(buf,sizeof(buf));
                        printf("爹:PID:%d  PPID:%d\n",getpid(),getppid());
                        fgets(buf,sizeof(buf),stdin);
                        printf("向大好儿发送:%s \n\n",buf);
                        write(fd[1],buf,strlen(buf));
                        if( strncmp(buf,"quit",4) == 0){ 
                                break;
                        }               }       }
        return 0;
}
:se
相关推荐
小郎君6582 小时前
Vue 多标签页的加载态设计:为什么我没有用 Suspense 实现 PageLoading
vue.js·算法
JJJennie7772 小时前
MAI Gateway私有化部署全攻略:大模型网关如何接入?附架构图
算法·gateway·ai网关·魔芋ai
CANI_PLUS2 小时前
电脑文件共享
运维·服务器
東隅已逝,桑榆非晚2 小时前
算法3.双指针法-快乐数
c++·笔记·学习·算法
专注仿真2 小时前
卷积神经网络(CNN)算法详解
人工智能·python·算法·代码·大模型训练
Decay__2 小时前
15_MySQL 数据同步与迁移方案 —— 复制 / DataX / Canal / 异构同步(对标 Oracle GoldenGate)
运维·数据库·sql·mysql·架构
FII工业富联科技服务3 小时前
多智能体如何进入制造现场?从业务协同到数字孪生验证
大数据·人工智能·算法·机器人·制造·数字孪生
Linux界最忧郁之人3 小时前
华为云ECS&IMS&AS实战|弹性云服务器、私有镜像、弹性伸缩完整实验
linux·运维·服务器·centos·华为云·openstack
≮傷£≯√3 小时前
httpserver_QNetWorkClient
算法
Evand J3 小时前
【PMSM例程11】永磁同步电机(PMSM)基于UKF的转速与转子位置估计。附下载链接
算法·matlab·卡尔曼滤波·永磁同步电机·ukf·pmsm·位置估计