进程间通信-有名管道

无名管道,由于没有名字,只能用于亲缘关系的进程间通信.。为了克服这个缺点,提出了有名管道(FIFO)。

FIFO不同于无名管道之处在于它提供了一个路径名与之关联,以FIFO的文件形式存在于文件系统中,这样,即使与FIFO的创建进程不存在亲缘关系的进程,只要可以访问该路径,就能够彼此通过FIFO相互通信,因此,通过FIFO不相关的进程也能交换数据。值的注意的是,FIFO严格遵循先进先出(first in firstout),对管道及FIFO的读总是从开始处返回数据,对它们的写则把数据添加到末尾。它们不支持诸如Lseek()等文件定位操作。有名管道的名字存在于文件系统中,内容存放在内存中。有名管道比无名管道多了一个打开操作:open

FIFO的打开规则:

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

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

1、             实验步骤演示

(1):首先在一个终端中编译写端然后运行。

可见进程无法继续执行下去,此时打开另一个终端,编译读过程并运行,显示如下:

而且在读终端执行显示结果的同时,执行写进程的终端显示也发生了变化。可见读写进程需要同时进行才可以完成有名管道的通信。

写端代码:
#include<unistd.h>
#include<stdlib.h>
#include<stdio.h>
#include<string.h>
#include<fcntl.h>
#include<limits.h>
#include<sys/types.h>
#include<sys/stat.h>

#define FIFO_NAME "/home/owen/myfifo/my_fifo"
//
int main(int argc,char *argv[])
{
    int pipe_fd;
    int res;
    char buffer[]="Hello world!";
    if(access(FIFO_NAME,F_OK)==-1)            //file exist
    {
        res=mkfifo(FIFO_NAME,0766);
        if(res!=0)
        {
            fprintf(stderr,"Could not creat fifo %s\n",FIFO_NAME);
            exit(1);
        }
    }
    printf("Process %d opening FIFO O_WRONLY\n",getpid());
    pipe_fd=open(FIFO_NAME,O_WRONLY);
    printf("the file`s descriptor is %d\n",pipe_fd);
    if(pipe_fd!=-1)
    {
        res=write(pipe_fd,buffer,sizeof(buffer));    // write data
        printf("write data is %s,%d bytes is writen\n",buffer,res);
        (void)close(pipe_fd);                //close
    }
    else
        exit(1);
    printf("Process %d finished\n",getpid());
    exit(1);
}
读端代码:
#include<unistd.h>
#include<stdlib.h>
#include<stdio.h>
#include<string.h>
#include<fcntl.h>
#include<limits.h>
#include<sys/types.h>
#include<sys/stat.h>

#define FIFO_NAME "/home/owen/myfifo/my_fifo"

int main(int argc,char *argv[])
{
    int pipe_fd;
    int res;
    char buffer[4096];
    int bytes_read=0;
    memset(buffer,'\0',sizeof(buffer));
    printf("Process %d opening FIFO O_RDONLY\n",getpid());
    pipe_fd=open(FIFO_NAME,O_RDONLY);
    printf("the file`s descriptor is %d\n",pipe_fd);
    if(pipe_fd!=-1)
    {
        bytes_read=read(pipe_fd,buffer,sizeof(buffer));
        printf("the read data is %s\n",buffer);
        close(pipe_fd);        //close
    }
    else
        exit(1);
    printf("Process %d finished,%d bytes read\n",getpid(),bytes_read);
    exit(1);
}

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值