1. 程式人生 > >Linux 程序間通訊 管道

Linux 程序間通訊 管道

管道

匿名管道:半雙工,資料單向流動,只能用與有親緣關係的程序間。

pipe_read_buf_small.c

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

int main(){
    int pipe_fd[2];
    pid_t pid;
//    char* r_buf;
//    char* w_buf;
    char r_buf[4096];
    char w_buf[4096*2];
    int r_num;
    int w_num;
    int count=0;

    if(pipe(pipe_fd)==-1){
        printf("Crate pipe error\n");
    }

    if((pid=fork())<0){
        printf("Fork error\n");
    }else if(pid==0){
        printf("Child:\n");
        close(pipe_fd[1]);
        while(1){
            sleep(1);
            if((r_num=read(pipe_fd[0],r_buf,1000))==-1){
                printf("Child read error\n");
            }else {
                printf("Child read successfully read:%d\n",r_num);
            }
            count++;
            if(count>10){
                break;
            }
        }
        close(pipe_fd[0]);
        printf("c dead\n");
        exit(0);
    }else{
        printf("Parent:\n");
        close(pipe_fd[0]);
        if((w_num=write(pipe_fd[1],w_buf,1024))<0){
            printf("p write error\n");
        }else{
            printf("p write successfully :%d\n",w_num);
        }
        w_num=write(pipe_fd[1],w_buf,4096);
        printf("p write suc 2 :%d\n",w_num);
        printf("p dead\n");
        exit(0);
    }
    return 0;
}

pipe_close_child_read.c

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

int main(){
    int pipe_fd[2];
    pid_t pid;
//    char* r_buf;
//    char* w_buf;
    char r_buf[4096];
    char w_buf[4096*2];
    int r_num;
    int w_num;
    int count=0;

    if(pipe(pipe_fd)==-1){
        printf("Crate pipe error\n");
    }

    if((pid=fork())<0){
        printf("Fork error\n");
    }else if(pid==0){
        printf("Child:\n");
        close(pipe_fd[1]);
        while(1){
            sleep(1);
            if((r_num=read(pipe_fd[0],r_buf,1000))==-1){
                printf("Child read error\n");
            }else {
                printf("Child read successfully read:%d\n",r_num);
            }
            count++;
            if(count>10){
                break;
            }
        }
        close(pipe_fd[0]);
        printf("c dead\n");
        exit(0);
    }else{
        printf("Parent:\n");
        close(pipe_fd[0]);
        if((w_num=write(pipe_fd[1],w_buf,1024))<0){
            printf("p write error\n");
        }else{
            printf("p write successfully :%d\n",w_num);
        }
        w_num=write(pipe_fd[1],w_buf,4096);
        printf("p write suc 2 :%d\n",w_num);
        printf("p dead\n");
        exit(0);
    }
    return 0;
}

pipe_close_parent_write.c

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

int main(){
    int pipe_fd[2];
    pid_t pid;
    char r_buf[10];
    char w_buf[4];
    int r_num;

    if(pipe(pipe_fd)==-1){
        printf("Open pipe error\n");
        return -1;
    }

    if((pid=fork())<0){
        printf("Fork error\n");
    }else if(pid==0){
        printf("Child process\n");
        close(pipe_fd[1]);//close write
        sleep(3);//make sure the parent process close write
        r_num=read(pipe_fd[0],r_buf,10);
        //printf("Read size:%d,%d\n",r_num,atoi(r_buf));
        printf("Read size:%d,%s\n",r_num,r_buf);
        close(pipe_fd[0]);
        printf("Child dead!\n");
        exit(0);
    }else if(pid>0){
        printf("Parent process\n");
        close(pipe_fd[0]);//close read
        strcpy(w_buf,"123");
        if(write(pipe_fd[1],w_buf,5)!=-1){
            printf("Write successfully\n");
        }
        close(pipe_fd[1]);
        printf("Parent process write has been closed!\n");
//        sleep(6);
        printf("Parent dead!\n");
        exit(0);
    }
    exit(0);
}

命名管道:可以在不具有親緣關係的程序間通訊。

FIFO_w.c

#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#include <fcntl.h>

#define FIFO_SERVER "/tmp/fifoserver"

int main(){
    int fd;
    char w_buf[4096*2];
    int w_num;
    if(mkfifo(FIFO_SERVER,O_CREAT|O_EXCL)<0){
        printf("Create fifo error\n");
    }
//    fd=open(FIFO_SERVER,O_WRONLY|O_NONBLOCK,0);
    fd=open(FIFO_SERVER,O_WRONLY,0);
    if(fd==-1){
        if(errno==ENXIO){
            printf("open error;no reading process\n");
        }
    }
    memset(w_buf,0,4096*2);
    w_num=write(fd,w_buf,2048);
    if(w_num==-1){
        if(errno==EAGAIN){
            printf("1write to fifo error, try later\n");
        }
    }else {
        printf("1write successfully:%d\n",w_num);
    }
    
    w_num=write(fd,w_buf,5000);
    if(w_num==-1){
        if(errno==EAGAIN){
            printf("2write to fifo error, try later\n");
        }
    }else {
        printf("2write successfully:%d\n",w_num);
    }
    
    return 0;
}

FIFO_r.c

#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#include <fcntl.h>

#define FIFO_SERVER "/tmp/fifoserver"
#define SIZE 4096
int main(int argc,char **argv){
    char r_buf[SIZE];
    int fd;
    int r_num=atoi(argv[1]);
    printf("Read wants to read:%d\n",r_num);

    //fd=open(FIFO_SERVER,O_RDONLY|O_NONBLOCK,0);
    fd=open(FIFO_SERVER,O_RDONLY,0);
    if(fd==-1){
        printf("open %s for read error\n",FIFO_SERVER);
        exit(0);
    }

    int count=0;
    while(1){
        r_num=read(fd,r_buf,SIZE);
        if(r_num==-1){
            if(errno==EAGAIN)
                printf("no data available\n");
        }else {
            printf("read OK :%d\n",r_num);
        }
        sleep(1);
        count++;
        if(count>20)break;
                 
    }
    unlink(FIFO_SERVER);
    return 0;
}
參考鄭彥興《Linux程序通訊》