码迷,mamicode.com
首页 > 其他好文 > 详细

ipc_pipe

时间:2020-01-19 19:21:05      阅读:79      评论:0      收藏:0      [点我收藏+]

标签:color   关闭   管道   file   生成   out   超过   lin   gets   

管道是最早的用来实现进程间通信的技术,有管道和FIFO(有名管道)之分,前者只能用于有继承关系的进程间通信,后者用于无继承(无fork() )关系进程间通信。

管道的内容存在于内核中,一个管道就是一个字节流。

使用管道注意的事项:

1)如果从空的管道中读取数据会被阻塞直到至少余一个字节被写入管道中为止。如果管道写入端关闭,读完管道中的数据后read()返回0.

2)管道是单向的。

3)当写入管道的数据不超过PIPE_BUF(Linux上4096)字节的操作是原子的!在多进程中要注意,否则数据不同步。

4)管道的容量是有限的,当写入管道的数据达到一定限度后在往该管道写入数据会被阻塞直到从该管道中移除部分数据。

两个进程要进行通信,一般都是要先使用pipe()创建管道后调用fork()生成子进程。

以下使用两个管道在两个进程间进行双向数据传送。

要注意的是父进程和子进程关闭管道的一些出口或入口是因为使用fork()后父子进程共享相同的打开文件。

#include<unistd.h>
#include<sys/wait.h>  //waitpid()
#include<string.h>  
#include<stdio.h>

#include<sys/stat.h>
#include<fcntl.h>
#include<stdlib.h>  //exit(0)

#include<errno.h> //errno
#define     MAXLINE  4096

void client(int, int );
void server(int, int);

// 辅助函数
int  Read(int   fd, char *buf,  int len)
{
    int n = read(fd, buf, len);
    if(-1 == n)
        printf("read error\n");
    
    return n;
}

void  Write(int  fd,  char * buf, int len)
{
    int     n = write(fd, buf, len);
    if(-1 == n)
        printf("client write error\n");
}

void    Close(int fd)
{
    if(-1 == close(fd))
        printf("close error\n");
}

int     main()
{
    int     pipe1[2], pipe2[2];
    pid_t   childpit;

    int     state;

    state = pipe(pipe1);
    if(state == -1)
        printf("create pipe 1 error\n");
    
    state = pipe(pipe2);
    if(state == -1)
        printf("create pipe 2 error\n");

    //<unistd.h>
    childpit = fork();

    if(childpit == 0)
    {
        if(-1 == close(pipe1[1]))
            printf("close pipe 1 error\n");
        if(-1 == close(pipe2[0]))
            printf("close pipe 2 error\n");

            server(pipe1[0], pipe2[1]);
            exit(0);
    }
    
    Close(pipe1[0]);
    Close(pipe2[1]);
    
    client(pipe2[0], pipe1[1]);

    if(-1 == waitpid(childpit, NULL, 0)) //等待子进程执行完
        printf("waitpid error\n");

    exit(0);
}

// 客户端
void    client(int  readfd, int writefd)
{
    size_t     len;
    ssize_t    n;
    char    buff[MAXLINE];

    if(NULL == fgets(buff, MAXLINE, stdin))
        printf("get pathname error\n");

    len = strlen(buff);

    if(buff[len-1] == \n)
        len--;
    
    if(-1 == write(writefd, buff, len))
        printf("write  error\n");

    while( (n = Read(readfd, buff, MAXLINE)) > 0)
        Write(STDOUT_FILENO, buff, n); //宏定义在unistd.h中
}

// 服务器
void    server(int  readfd, int  writefd)
{
    int     fd;
    ssize_t     n;
    char    buff[MAXLINE];

    if( (n = Read(readfd, buff, MAXLINE)) == 0)
    {
        printf("end-of-file while reading pathname");
        exit(0);
    }
    buff[n] = \0;

    if( (fd = open(buff, O_RDONLY)) < 0)
    {
        snprintf(buff + n, sizeof(buff) - n, " : can‘t open, %s\n", strerror(errno));

        n = strlen(buff);
        Write(writefd, buff, n);
    }else{
        while( (n = Read(fd, buff, MAXLINE)) > 0)
            Write(writefd, buff, n);
        Close(fd);
    }
}


ipc_pipe

标签:color   关闭   管道   file   生成   out   超过   lin   gets   

原文地址:https://www.cnblogs.com/ilove-haha/p/12147592.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!