Unix进程间的通信

1. 管道可以用作父子进程之间的通信,pipe函数,将fd[0]打开用于读取数据,fd[1]打开用于写入数据。通常,对于单方向通信,读端会关闭写fd,即fd[1],写端会关闭读fd,即fd[0]

int main() {
    int fd[2];
    int err = pipe(fd);
    char *str = "Hello...";
    //write(fd[1], str, strlen(str));
    err = fork();
    if (err == 0) {
        // child
        write(fd[1], str, strlen(str));
        char buf[30] = {0};
        read(fd[0], buf, 30);
        sleep(2);
        write(STDOUT_FILENO, buf, strlen(buf));
        exit(0);
    } else {
        char buf[30];
        fgets(buf, 30, stdin);
        write(fd[1], buf, strlen(buf));
        waitpid(err, 0, 0);
    }
}
void test2() {
    char buf[1000];
    
    // ls | xargs echo
    FILE *f = popen("ls", "r");
     while (0 != fgets(buf, 1000, f)) {
         printf("msg is: %s\n", buf);
     }
    //popen打开的文件,必须使用pclose关闭,而不能使用fclose关闭,否则后续读写会有问题
     printf("ret code is: %d\n", pclose(f));

    // echo 'hi,Jenny' | sed 's/hi/Hello/g'
    FILE *f2 = popen("sed 's/hi/Hello/g'", "w");
    fputs("hi,Jenny", f2);
    pclose(f2);
}

2. fifo 就像是一个文件。可以执行命令mkfifo或者使用mkfifo函数创建fifo。创建的文件的标志会持久化在磁盘上,但是fifo的内容和进程的声明周期是相同的,也就是如果进程关闭这个fd(准确的说是所有进程都关闭这个fd),则写入fifo的数据就不复存在了。可以使用ls -F选项查看文件类型,fifo会以|结尾,属性以p开头。如果一个进程企图为只读打开一个没有等待写入的fifo,会阻塞;如果一个进程企图为只写打开一个没有等待读取的fifo,会阻塞。为读写而打开的fifo不会被阻塞。

int main() {
    mkfifo("/tmp/srv",S_IRWXU|S_IRGRP|S_IROTH);
    int fd = open("/tmp/srv", O_RDWR);
    printf("the fd is %d\n", fd);

    for (;;){
        write(fd, "Hello, world!", 5);
        sleep(1);
    }
}

3. 对于pipe或者fifo,如果请求读出的数据量小于pipe/fifo中的数据量,则只返回可用数据;如果请求写入的数据量小于PIPE_BUF,则write操作是原子的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值