Chinaunix首页 | 论坛 | 博客
  • 博客访问: 300427
  • 博文数量: 63
  • 博客积分: 1482
  • 博客等级: 上尉
  • 技术积分: 1185
  • 用 户 组: 普通用户
  • 注册时间: 2011-03-12 19:06
个人简介

hello world!

文章分类

全部博文(63)

分类: LINUX

2012-08-20 18:11:16

                 进程间的通信-FIFO 

  一、前言

         管道分为有名管道和无名管道。

无名管道只能用于有亲系关系的进程间通信,即只能在父进程与子进程或兄弟进程间通信。有名管道可以用于任何进程间通信。管道有半双工,即在某一时刻只能有一个进程向管道里读或写。

管道是Unix系统IPC中最古老的的形式,管道有下面两种局限性:

1)   历史上它们是半双工的(即数据只能在一个方向上流动);

2)   它们只能在具有公共祖先的进程之间使用,一个管道由一个进程创建,然后该进程调用 fork(),此后,父子进行之间就可应用该管道。

 

二、无名管道

         调用fork后,要做什么取决于我们想要在的数据流的方向。对于从父进程到子进程的管道,父进程关闭管道的读端fd[0],子进程则关闭写端fd[1]

 

 

1、  pipe函数

管道的创建。

#include

int pipe(int filedes[2]);

filedes:参数返回两个文件描述符:filedes[0]为读而打开,filedes[1]为写而打开,filedes[1]的输出是filedes[0]的输入;

shmflgIPC_CREATIPC_EXCL

2、  无名管道实例

创建FIFOfork,在父进程关闭读,子进程关闭写;实现半双工的管道通信。

#include

 

#include

#include

#include

#include

 

int main(void)

{

    int n, fd[2];

    pid_t pid;

    char line[100];

 

   if(pipe(fd)<0)

        printf("[%s:%d]: pipe error! \n",__FUNCTION__,__LINE__);

   if((pid = fork())<0)

         printf("[%s:%d]: fork error! \n",__FUNCTION__,__LINE__);

   else if(pid>0)  //parant

   {

         close(fd[0]);

          write(fd[1],"hello word\n",12);

   }else

    {

        close(fd[1]);

       n = read(fd[0],line,sizeof(line));

       printf("[%s:%d]: FIFO date = %s \n",__FUNCTION__,__LINE__,line);

    }

    exit (0);

}

运行结果为:

# gcc fifo.c -o lcl

# ./lcl

[main:26]: FIFO date = hello word

 

三、有名管道

管道应用的一个重大限制是它没有名字因此,只能用于具有亲缘关系的进程间通信,有名管道(named pipeFIFO)提出后,该限制得到了克服。这样,即使与FIFO的创建进程不存在亲缘关系的进程,只要可以访问该路径,就能够彼此通过FIFO相互通信。遵循先入先出,不支持lseek()定位。

1、  mkfifo函数

             创建FIFO管道。

#include

#include

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

2、  有名管道的打开规则

有名管道比无名管道多一个打开操作:openFIFO的打开规则。

如果当前打开操作是为读而打开FIFO时,若已经有相应进程为写而打开该FIFO,则当前打开操作将成功返回;否则,可能阻塞直到有相应进程为写而打开该FIFO(当前打开设置了阻塞标志);或者成功返回。

3、  有名管道的读写规则

FIFO读数据:设置阻塞标志,当读取数据时,如果当前FIFO中有数据时,而其他进程正在进行读这些数据,或者无数据时,会阻塞当前进程。

读打开的阻塞标志,只对本进程的第一个读操作有作用,其实要执行的读操作将不再阻塞。

四、有名管道实例

 

#include

#include

#include

#include

#define FIFO "/home/lichenglong/study_key/FIFO"

 

int main()

{

         char buffer[80];

         int fd;

        

         unlink(FIFO);

         mkfifo(FIFO,0666);

         if(fork()>0)

         {

                   char s[] = "hello!\n";

                   fd = open(FIFO,O_WRONLY);

                   write(fd,s,sizeof(s));

                   close(fd);

         }else

         {       

                   fd = open(FIFO,O_RDONLY);

                   read(fd,buffer,80);

                   printf("read data: %s",buffer);

                   close(fd);

         }

}

运行结果

# gcc Gfifo.c

# ./a.out

read data: hello!

 

 

 

阅读(3448) | 评论(0) | 转发(1) |
给主人留下些什么吧!~~