管道通信習題

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;
}

運行截圖:

在這裏插入圖片描述

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