进程间通信-有名管道

来源:互联网 发布:网络重庆时时彩骗局 编辑:程序博客网 时间:2024/06/08 05:59

无名管道,由于没有名字,只能用于亲缘关系的进程间通信.。为了克服这个缺点,提出了有名管道(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);}

1 0
原创粉丝点击