系统编程:管道

无名管道

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;
}
相关推荐
-一杯为品-1 分钟前
【51单片机】程序实验5&6.独立按键-矩阵按键
c语言·笔记·学习·51单片机·硬件工程
运维老司机19 分钟前
Jenkins修改LOGO
运维·自动化·jenkins
D-海漠35 分钟前
基础自动化系统的特点
运维·自动化
我言秋日胜春朝★43 分钟前
【Linux】进程地址空间
linux·运维·服务器
爱摸鱼的孔乙己1 小时前
【数据结构】链表(leetcode)
c语言·数据结构·c++·链表·csdn
Dola_Pan1 小时前
C语言:数组转换指针的时机
c语言·开发语言·算法
繁依Fanyi1 小时前
简易安卓句分器实现
java·服务器·开发语言·算法·eclipse
C-cat.1 小时前
Linux|环境变量
linux·运维·服务器
yunfanleo1 小时前
docker run m3e 配置网络,自动重启,GPU等 配置渠道要点
linux·运维·docker
m51271 小时前
LinuxC语言
java·服务器·前端