系统编程:管道

无名管道

pipe()创建管道,半双工,所以在使用时候close()另外一个;

适合在有血缘关系的进程中使用,如 父子进程;

1.简单应用:

fork()函数创建子进程

pipe()函数创建管道

read()和write()函数完成读写

c 复制代码
#include <stdio.h>
#include <unistd.h>
#include <string.h>
int main()
{
    int fd[2];
    if(pipe(fd)==-1)return -1;  //创建管道,返回-1表示失败

    if(fork()==0){
        //子进程,写入
        close(fd[0]);
    while(1)
    {
        char buf[128];
        ssize_t len=read(0,buf,128);  //read默认会阻塞,等待输入
        buf[len]=0;

        printf("子进程写入数据%s\n",buf);
        write(fd[1],buf,128);  
    }
        _exit(0);

    }

    //父进程
    close(fd[1]);
    for (int i = 0; i < 3; i++)
    {
        char buf[128];

        ssize_t len=read(fd[0],buf,128);
        buf[len]=0;
        printf("主进程收到的内容:%s\n",buf);
    }
    close(fd[0]);
    //关闭读后,子进程会 收到信号,会退出;
    printf("main over\n");
    return 0;
}

2.父子进程实现命令中管道的功能,如:ps -A | grep bash

dup2()函数完成文件标识符的重定向

execlp()函数开始一个新的进程执行其中的命令

c 复制代码
int main()
{
    int fd[2];
    if(pipe(fd)==-1) return -1;  //管道创建失败
    if(fork()==0)
    {
        //子进程-读取数据从管道中
        close(fd[1]);
        dup2(fd[0],0);//管道的内容将被视为标准键盘输入
        execlp("grep","grep","bash",NULL);//grep命令可以将从键盘输入的内容进行过滤

        _exit(0);//子进程退出
    }
    //父进程-写入到管道中
    close(fd[0]);
    dup2(fd[1],1);//标准输出将被视为 管道输入内容
    execlp("ps","ps","-A",NULL);//执行命令输出

    return 0;
}

有名管道

会以文件出现,内容出现在内存中

适合用于没有血缘关系的多个进程中
1.两个进程通信,demo2与demo1

默认阻塞模式下:

被阻塞的条件:管道两边打开,但是没有内容时;

在指定为非阻塞模式时:

int fd =open("fifo1",O_WRONLY|O_NONBLOCK);增加O_NONBLOCK模式,表示不阻塞,但是读进程退出后,写进程会退出

demo1.c

c 复制代码
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <sys/stat.h>
int main(int argc,char *argv[]){

if(mkfifo("fifo1",0666)!= 0){  //创建有名管道,用完需要删掉
    perror("mkfifo");
    return -1;
}
	printf("fifo1已经创建\n");
	int fd = open("fifo1",O_RDONLY); //如果没有第二个以只写打开,将持续阻塞
	printf("--open fifo1--\n");
	while(1){     
	    char buf[128];
	    ssize_t len =read(fd,buf,128);
	    buf[len]=0;
	    printf("读取数据为:%s\n",buf);
	    sleep(2);
	}

return 0;
}

demo2.c

c 复制代码
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <sys/stat.h>
int main(int argc,char *argv[])
{
    int fd =open("fifo1",O_WRONLY);//int fd =open("fifo1",O_WRONLY|O_NONBLOCK);增加O_NONBLOCK模式,表示不阻塞,但是读进程退出后,写进程会退出
//被阻塞的条件:管道打开且没有数据时
 while(1){
    char buf[128];
    ssize_t len=read(0,buf,128);
    buf[len]=0;
    write(fd,buf,len);
    if(strncmp(buf,"sxit",4)==0)break;
    }
    close(fd);
    return 0;
}
相关推荐
分布式存储与RustFS5 分钟前
rclone 与 mc mirror:S3 对象存储同步,限速、过滤、断点续传实测对比
运维·云原生·开源·对象存储·分布式存储·s3·性能基准
祖力5521 分钟前
驱动工程搭建与字符设备驱动框架
linux·运维·服务器·内核·arm·imx6ull·驱动
发量惊人的中年网工27 分钟前
SD-WAN 组网方案怎么选?跨地域与多分支企业的选型指南(含成本对比)
服务器·网络·数据库
第25小时记录28 分钟前
[2026] Linux安装教程
运维·python
斯晨的AI笔记39 分钟前
在服务器上跑 npm ci 四十分钟没装完,我打包把 node_modules 扔了过去
服务器·node.js
endeavor121 小时前
can总线(五)
c语言·stm32·单片机·can
曦樂~1 小时前
Symmetric Ciphers对称加密
运维·服务器
mister_guo1 小时前
Elasticsearch:原理、Docker 安装与常用命令
大数据·运维·elasticsearch
Escalating_xu2 小时前
【Linux 网络编程】网络基础概念(下):IP、端口、Socket 与网络字节序,写代码前先打好基础
linux·网络·tcp/ip
刚入门的大一新生2 小时前
Linux-Ext系列文件系统
linux·运维·服务器