zoukankan      html  css  js  c++  java
  • 进程通信---FIFO

    管道没有名字,所以只能在具有血缘关系的进程间使用,而在无名管道发展出来的有名管道FIFO,则有路径名与之相关联,以一种特殊设备文件形式存在于文件系统中,从而允许无亲缘关系的进程访问FIFO,下面看FIFO的详细操作

    1.FIFO的建立

    FIFO是存在于文件系统的文件节点,所以我们可以建立文件节点的mknod系统用来建立它,也可以mkfifo系统调用

    mkfifo说明:

    #include

    #include

    int mkfifo(char *path,mode_t mode);

    说明:path:路径名,mode:指定文件存取权标志,mkfifo()会依参数pathname建立特殊的FIFO文件,该文件必须不存在,系统调用已经指定O_CREATE|O_EXCL

    返回:若成功则返回0,否则返回-1,错误原因存于errno中。
    错误代码
    EACCESS 参数pathname所指定的目录路径无可执行的权限
    EEXIST 参数pathname所指定的文件已存在。
    ENAMETOOLONG 参数pathname的路径名称太长。
    ENOENT 参数pathname包含的目录不存在
    ENOSPC 文件系统的剩余空间不足
    ENOTDIR 参数pathname路径中的目录存在但却非真正的目录。
    EROFS 参数pathname指定的文件存在于只读文件系统内。

    2.FIFO使用

    创建后,在读写前,要先打开它,用open系统调用

    当使用open()来打开 FIFO文件时,O_NONBLOCK旗标会有影响
    1、当使用O_NONBLOCK 旗标时,打开FIFO 文件来读取的操作会立刻返回,但是若还没有其他进程打开FIFO 文件来读取,则写入的操作会返回ENXIO 错误代码。
    2、没有使用O_NONBLOCK 旗标时,打开FIFO 来读取的操作会等到其他进程打开FIFO文件来写入才正常返回。同样地,打开FIFO文件来写入的操作会等到其他进程打开FIFO 文件来读取后才正常返回。

    下面练习,分别写两个程序,一个是服务器程序,不断从管道读取客户发送的信息;另一个是客户程序,在命令行输入信息并从管道发送:

    客户程序(写管道)

    1. /*fifo_write.c*/  
    2. #include   
    3. #include   
    4. #include   
    5. #include   
    6. #include   
    7. #include   
    8. #include   
    9.   
    10. /*FIFO管道路径*/  
    11. #define FIFO_SERVER "/tmp/myfifo"  
    12.   
    13. main(int argc,char** argv)  
    14. {  
    15.     int fd = 0;  
    16.     char w_buf[100];  
    17.     int nwrite;  
    18.     /*打开FIFO管道*/  
    19.     fd=open(FIFO_SERVER,O_WRONLY|O_NONBLOCK,0);  
    20.     if(fd==-1)  
    21.         if(errno==ENXIO)  
    22.             printf("open error; no reading process ");  
    23.     /*判断有没有参数输入*/  
    24.     if(argc==1)  
    25.         printf("Please send something ");  
    26.     /*复制参数输入*/  
    27.     strcpy(w_buf,argv[1]);  
    28.     /*写到FIFO去*/  
    29.     if((nwrite=write(fd,w_buf,100))==-1)  
    30.     {  
    31.         if(errno==EAGAIN)  
    32.             printf("The FIFO has not been read yet.Please try later ");  
    33.     }  
    34.     else   
    35.         /*输出写入的内容*/  
    36.         printf("write %s to the FIFO ",w_buf);  
    37. }  

    服务程序(读管道)

    1. /*fifo_read.c*/  
    2. #include   
    3. #include   
    4. #include   
    5. #include   
    6. #include   
    7. #include   
    8. #include   
    9.   
    10. /*定义FIFO路径*/  
    11. #define FIFO "/tmp/myfifo"  
    12.   
    13. main(int argc,char** argv)  
    14. {  
    15.     char buf_r[100];  
    16.     int  fd;  
    17.     int  nread;  
    18.     /*创建FIFO管道*/  
    19.     if((mkfifo(FIFO,O_CREAT|O_EXCL)<0)&&(errno!=EEXIST))  
    20.         printf("cannot create fifoserver ");  
    21.     printf("Preparing for reading bytes... ");  
    22.       
    23.     memset(buf_r,0,sizeof(buf_r));  
    24.     /*打开FIFO管道,不阻塞方式*/  
    25.     fd=open(FIFO,O_RDONLY|O_NONBLOCK,0);  
    26.     if(fd==-1)  
    27.     {  
    28.         perror("open");  
    29.         exit(1);      
    30.     }  
    31.     while(1)  
    32.     {  
    33.         memset(buf_r,0,sizeof(buf_r));  
    34.         /*读管道,因为定义了非阻塞方式,故在此不会阻塞进程*/  
    35.         if((nread=read(fd,buf_r,100))==-1){  
    36.             if(errno==EAGAIN)  
    37.                 printf("no data yet ");  
    38.         }  
    39.         printf("read %s from FIFO ",buf_r);  
    40.         sleep(1);  
    41.     }     
    42.     pause();  
    43.     unlink(FIFO);  
    44. }  

    接下来进行编译,编译好后,在Linux中运行两个终端,分别运行以上两个程序,可以看到,运行fifo_read时,程序一直在每隔一秒读,然后我们在另一个终端输入:

    $ ./fifo_write helloworld

    可以看出fifo_read显示出“helloworld”,说明接受成功

    FIFO的一些注意问题:

    (1)管道数据的FIFO处理方式

    首先放入管道的数据,在端口首先被读出

    (2)管道数据的不可再现性

    已读取的数据在管道里消失,不能再读

    (3)管道长度的有限性

    (4)SIGPIPE信号 如果一个进程试图写入到一个没有读取到进程的管道中哦你,系统内核产生SIGPIPE信号

    转自:http://blog.chinaunix.net/uid-22278460-id-1777637.html

  • 相关阅读:
    springMVC-1
    8-IO总结
    7-RandomAccessFile 随机流
    6-对象流(对象的序列化)
    正则表达式语法手册,以及一些实例
    JavaScript的屏幕对象
    js常用正则表达式表单验证代码
    使用 CSS3 实现超炫的 Loading(加载)动画效果
    ajax处理跨域有几种方式
    javascript实现图片延迟加载方法汇总(三种方法)
  • 原文地址:https://www.cnblogs.com/chengxuzhixin/p/4930944.html
Copyright © 2011-2022 走看看