进程间的通信-FIFO

一、 前言

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

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

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

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

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

 

二、无名管道

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

 

 

1、  pipe 函数

管道的创建。

#include <unistd.h>

int pipe(int filedes[2]);

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

shmflgIPC_CREATIPC_EXCL

2、   无名管道实例

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

#include <stdio.h>

 

#include <unistd.h>

#include <sys/types.h>

#include <fcntl.h>

#include <sys/ioctl.h>

 

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 <sys/stat.h>

#include <sys/types.h>

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

2、   有名管道的打开规则

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

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

3、   有名管道的读写规则

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

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

四、有名管道实例

 

#include <stdio.h>

#include <sys/stat.h>

#include <sys/types.h>

#include <fcntl.h>

#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!


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值