系统编程:管道

无名管道

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;
}
相关推荐
WTT001119 分钟前
2024楚慧杯WP
大数据·运维·网络·安全·web安全·ctf
苹果醋327 分钟前
React源码02 - 基础知识 React API 一览
java·运维·spring boot·mysql·nginx
了一li1 小时前
Qt中的QProcess与Boost.Interprocess:实现多进程编程
服务器·数据库·qt
日记跟新中1 小时前
Ubuntu20.04 修改root密码
linux·运维·服务器
唐小旭1 小时前
服务器建立-错误:pyenv环境建立后python版本不对
运维·服务器·python
码农君莫笑1 小时前
信管通低代码信息管理系统应用平台
linux·数据库·windows·低代码·c#·.net·visual studio
明 庭1 小时前
Ubuntu下通过Docker部署NGINX服务器
服务器·ubuntu·docker
BUG 4041 小时前
Linux——Shell
linux·运维·服务器
007php0071 小时前
Go语言zero项目部署后启动失败问题分析与解决
java·服务器·网络·python·golang·php·ai编程