管道通信习题

1.编程实现命名管道通信,进程a向进程b每隔3秒发送字符串”hello world”

实现思路:

​ 利用进程从管道读数据时若没有其他进程进行写数据,那么进程会阻塞这一原理。实现write进程只要定时(3s)向管道内写数据,read进程就会在管道内有数据后读出数据并显示。 当关闭write进程后,read进程不会再阻塞,此时会不停地从管道中读出空数据,所以判断当从管道内读出空数据时,read进程退出。

read.c:

#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <fcntl.h>

int main(int argc, char *argv[]){
    int fd;
    int n;
    pid_t pid;
    char msg[20] = {0};
    
    if(unlink("my_fifo") != 0){
        perror("unlink fifo");
    }
    if(mkfifo("my_fifo", S_IRUSR|S_IWUSR) != 0){
        perror("mkfifo");
    }
    
    fd = open("my_fifo", O_RDONLY);
    
    while(1){
        n = read(fd, msg, sizeof(msg));
        printf("read to my_fifo buf=%s\n", msg);
        
        if(n == 0) break;
    }
    
    return 0;
}

write.c

#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <fcntl.h>

int main(int argc, char *argv[]){
    int fd;
    pid_t pid;
    char msg[] = "hello world";
    
    fd = open("my_fifo", O_WRONLY);
    
    while(1){
        printf("before write\n");
        write(fd, msg, strlen(msg));
        sleep(3);
    }
    return 0;
}

运行截图:

在这里插入图片描述

2.使用管道模拟shell命令 :cat file | wc -l,子进程实现cat file命令将结果返回给父进程,父进程再实现wc -l命令

instruct.c

#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <fcntl.h>

int main(int argc, char *argv[]){
    pid_t pid;
    char buf[50];
    
    if(argc < 2){
        printf("usage: <filename>\n");
        return 0;
    }
    
    if(unlink("my_fifo") != 0){
        perror("unlink fifo");
    }
    if(mkfifo("my_fifo", S_IRUSR|S_IWUSR) != 0){
        perror("mkfifo");
    }
    
    pid = fork();
    if(pid < 0){
        perror("fork");
        exit(-1);
    }
    if(pid == 0){
        int chrfd = open("my_fifo", O_WRONLY);
        dup2(chrfd, 1);//用管道替换掉标准输出
        execlp("cat", "cat", argv[1], NULL);
    }else{
        int parfd = open("my_fifo", O_RDONLY);
        dup2(parfd, 0);//用管道替换掉标准输入
        execlp("wc", "wc", "-l", NULL);
    }
        
    return 0;
}

运行截图:

在这里插入图片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章