【读书笔记】管道和FIFO

管道

  提供一个单路(单向)数据流,可以为两个不同进程提供进程间的通信手段

#include <unistd.h>

    int pipe(int fd[2]);

  返回两个文件描述符,fd[0]() 和 fd[1]()

  管道间的通信通常是使用 read 和 write 函数完成的

 

  管道的典型用法:

    首先,由父进程创建一个管道,然后调用fork派生一个自身的副本

    接着,父进程关闭管道的读端,子进程关闭管道的写段

    这样就在父子进程间提供了一个单向数据流

 

  双管道:

    当需要一个双向数据流的时候,我们必须创建两个管道,每个方向一个

int    pipe1[2], pipe2[2];
pid_t childpid;

Pipe(pipe1);
Pipe(pipe2);

if( (childpid = Fork()) ==0 )
{
    Close(pipe1[1]);
    Close(pipe2[0]);

    /*代码*/

    exit(0);
}

Close(pipe1[0]);
Close(pipe2[1]);

/*代码*/

Waitpid(childpid, NULL, 0);
exit(0);

 

 

 

 

FIFO

  指代先进先出(first in, first out),是一个单向数据流

  不同于管道的是,每个FIFO有一个路径名与之关联,从而允许无亲缘关系的进程访问同一个FIFO,因而也称"有名管道"。(我更愿意把它看做一个文件

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

int mkfifo(const char* pathname, mode_t mode);

  pathname是一个路径名,也是该FIFO的名字

  mode指文件的权限位

常值 说明

S_IRUSR

S_IWUSR

用户(属主)读

用户(属主)写

S_IRGRP

S_IWGRP

(属)组成员读

(属)组成员写

S_IROTH

S_IWOTH

其他成员读

其他成员写

    常值 FIFO_MODE 在 unpipc.h 中定义:

#define FIFE_MODE ( S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH )

 

  与管道不同的是:

    创建并打开一个管道只需用 pipe,创建并打开一个FIFO则需要调用 mkfifo 后再调用 open

    管道在所有进程都关闭它后自动消失,FIFO的名字则只有通过调用 unlink 才从文件系统中删除

#define FIFO1 "/tmp/fifo.1"
#define FIFO2 "/tmp/fifo.2"


int readfd, writefd;
pid_t childpid;

if( (mkfifo(FIFO1, FILE_MODE) < 0) && (errno != EEXIST) )
    err_sys("can't create %s", FIFO1);
if( (mkfifo(FIFO2, FILE_MODE) < 0) && (errno != EEXIST) )
{
    unlink(FIFO1);  
    err_sys("can't create %s", FIFO2);
}

if( (childpid = Fork()) ==0 )
{
    readfd = Open(FIFO1, O_RDONLY, 0);
    writefd = Open(FIFO2, O_WRONLY, 0);

    /*代码*/
    //为什么这里不需要Close(readfd) Close(writefd)

  exit(0); 
}

writefd = Open(FIFO1, O_WRONLY, 0);
readfd = Open(FIFO2, O_RDONLY, 0);

/*代码*/ 

Waitpid(childpid, NULL, 0); 

Close(readfd); 
Close(writefd); 

Unlink(FIFO1); 
Unlink(FIFO2); 
exit(0);

 

 

 

 

 

posted @ 2013-09-12 22:14  阿祖叔叔  阅读(422)  评论(1编辑  收藏  举报