系统编程:管道

无名管道

pipe()创建管道,半双工,所以在使用时候close()另外一个;
适合在有血缘关系的进程中使用,如 父子进程;

1.简单应用:

fork()函数创建子进程
pipe()函数创建管道
read()和write()函数完成读写

#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()函数开始一个新的进程执行其中的命令

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

#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

#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;
}
  • 6
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值