系统编程:管道

无名管道

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 小时前
uniapp-是否删除
linux·前端·uni-app
闲晨1 小时前
C++ 继承:代码传承的魔法棒,开启奇幻编程之旅
java·c语言·开发语言·c++·经验分享
_.Switch2 小时前
高级Python自动化运维:容器安全与网络策略的深度解析
运维·网络·python·安全·自动化·devops
2401_850410832 小时前
文件系统和日志管理
linux·运维·服务器
JokerSZ.2 小时前
【基于LSM的ELF文件安全模块设计】参考
运维·网络·安全
XMYX-02 小时前
使用 SSH 蜜罐提升安全性和记录攻击活动
linux·ssh
芯盾时代2 小时前
数字身份发展趋势前瞻:身份韧性与安全
运维·安全·网络安全·密码学·信息与通信
心灵彼岸-诗和远方3 小时前
DevOps业务价值流:架构设计最佳实践
运维·产品经理·devops
一只哒布刘3 小时前
NFS服务器
运维·服务器
苹果醋34 小时前
Java8->Java19的初步探索
java·运维·spring boot·mysql·nginx