分享

Linux进程间通信——有名管道

 lifei_szdz 2014-04-17
1 创建有名管道
//come from /user/include/sys/stat.h
extern int mkfifo (_const char *_path,_mode_t _mode);

mkfifo()会根据参数来创建特殊的有名管道文件,该文件要求必须不存在,而且参数mode为该文件的权限,mkfifo()创建的FIFO文件的其他进程都可以用读写一般文件的方式存取。如果该函数执行成功将返回0,否则返回-1,失败原因将存储于errno中。
2 读写有名管道
//come from /user/include/unistd.h
extern ssize_t read (int _fd,void *_buf,size_t _nbytes);
extern ssize_t write (int _fd,_const void *_buf,size_t _n);
如果希望打开管道写端,则需要另一个进程打开管道读端,整个程序才能正常进行;如果只打开有名管道的一端,则系统将暂时阻塞打开进程,直到有另一个进程打开该管道的另一端,当前进程才会继续执行。
3 例子
非父子进程采用有名管道通信实例:
向有名管道中发送数据的进程源代码如下:
#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/crosslandy/Linux/PIPE/my_fifo"

int main(int argc,char *argv[])
{
    int pipe_fd;
    int res;
    char buffer[]="Hello world!";
    if(access(FIFO_NAME,F_OK)==-1)            //文件是否存在
    {
        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));    // 写书据
        printf("write data is %s,%d bytes is writen\n",buffer,res);
        (void)close(pipe_fd);                //切记关闭文件描述符   
    }
    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/crosslandy/Linux/PIPE/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);        //不解释
    }
    else
        exit(1);
    printf("Process %d finished,%d bytes read\n",getpid(),bytes_read);
    exit(1);
}
编译运行如下:
首先编译写过程:如下
[crosslandy@localhost PIPE]$ gcc -o fifo_write fifo_write.c
[crosslandy@localhost PIPE]$ ./fifo_write
Process 4182 opening FIFO O_WRONLY
可见无法继续执行下去,此时另外打开一个终端,编译读过程并运行则在此终端下显示如下:

 [crosslandy@localhost PIPE]$ gcc -o fifo_read fifo_read.c
[crosslandy@localhost PIPE]$ ./fifo_read
Process 4771 opening FIFO O_RDONLY
the file`s descriptor is 3
the read data is Hello world!
Process 4771 finished,13 bytes read
并且在此终端显示出结果的同时,执行写进程的终端显示发生变化如下:
[crosslandy@localhost PIPE]$ gcc -o fifo_write fifo_write.c
[crosslandy@localhost PIPE]$ ./fifo_write
Process 4182 opening FIFO O_WRONLY






the file`s descriptor is 3
write data is Hello world!,13 bytes is writen
Process 4182 finished
可见读写进程需要同时进行才能完成有名管道的通信。

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多