2023操作系统-进程间通信-管道

79 阅读1分钟

无名管道: 适用于有亲缘关系进程之间通信

有名管道: 适用于无亲缘关系进程之间通信

管道的特点

管道继承性
    父子通信
    兄弟通信

单向 无结构的字节流 无边界
阻塞
读完就没了


字符设备
块设备
管道文件
socket文件

不占磁盘block 仅占inode
d
f
p

通过bash命令创建管道体验

ls|grep a

mkfifo pipe
ls > pipe
cat < pipe

无名管道

情形1: image.png

#include <sys/types.h>
#include <unistd.h>

int main(int argc, char const *argv[]) {
    int fd[2];
    int pp = pipe(fd);
    char buf[128];
    for (int i = 0; i < 10; i++) {
        write(fd[1],"hello",5);
        sleep(1);
        int r = read(fd[0],buf,128);
        write(1,buf,r);
    }
    close(fd[0]);
    close(fd[1]);
}

情形2: image.png

#include <unistd.h>
#include <sys/wait.h>
#include <stdlib.h>


int main(int argc, char const *argv[]) {
    int fd[2];
    int pp = pipe(fd);

    char buf[128];
    if (fork() == 0) {
        close(fd[1]);
        for (int i = 0; i < 10; i++) {
            int r = read(fd[0], buf, 128);
            write(1, buf, r);
        }
        close(fd[0]);
        exit(0);
    } else {
        close(fd[0]);
        for (int i = 0; i < 10; i++) {
            write(fd[1], "hello", 5);
            sleep(1);
        }
        wait(NULL);
        close(fd[1]);
    }
}

情形3:

image.png

有名管道

//创建管道
#include <stdio.h>
#include <sys/stat.h>

int main(int argc, char const *argv[]) {
    int res = mkfifo("./mypipe", 0777);
    if (res < 0) {
        perror("mkfifo");
    }
}


//读端代码
#include <stdio.h>
#include <sys/stat.h>

int main(int argc, char const *argv[]) {
    int fd = open("./mypipe2",O_RDONLY);
    char buf[128];
    int n = read(fd,buf,128);
    write(1,buf,n);
    while (1);
    close(fd);
}
//写端代码
#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>


int main(int argc, char const *argv[]) {
    int fd = open("./mypipe2",O_WRONLY);
    write(fd, "hello",5);
    while (1);
    close(fd);
}

先运行读端,在运行写端观察.