码迷,mamicode.com
首页 > 系统相关 > 详细

进程通信——有名管道

时间:2015-12-20 23:56:14      阅读:321      评论:0      收藏:0      [点我收藏+]

标签:

上一篇文章中学习了进程间通信的一种简答的方法:匿名管道。但是它只能用于具有亲缘关系的进程之间的通信。而FIFO的通信机制与之相似,却可以在任意两个进程之间通信。

FIFO文件操作

创建FIFO类似于创建文件,确实,FIFO可以存在于文件系统中。下面是创建FIFO的函数:

#include <sys/stat.h>
int mkfifi(const char *pathname, mode_t mode);
                                返回值:若成功返回0,若出错返回-1

参数说明:

pathname: FIFO文件的路径
mode: 设置FIFO文件属性的模式字,通常设为0666
返回值:若成功返回0,若出错返回-1

下面是一个简答的利用mkfifo函数来创建FIFO文件的例子,并利用了ls命令来查看其属性:

int ret;
mode_t mode = 0666;
if ((ret = mkfifo("./fifo",  mode)) < 0)
{
    printf("mkfifo error the return code is %s\n", strerror(errno));
    return -1;
}

技术分享

在创建好FIFO文件之后,需要调用 open 函数打开FIFO文件,然后在此基础上执行read write 等操作。下面是关于 FIFO 文件操作的一些注意点。

注意点:

  

  • 跟管道类似,如果对写进程不存在的FIFO执行read操作,总是返回0;这意味着如果写进程提前关闭FIFO文件,并且FIFO中不存在数据时,read操作将直接返回0,而不会阻塞。如果对进程不存在的FIFO执行write操作,出错返回-1,产生SIGPIPE信号。
  • 如果open时没有设置O_NONBLOCK,则以读方式打开FIFO文件,必须存在以写方式打开此FIFO文件的进程,否则一直阻塞;以写方式打开FIFO,如果不存在以读方式打开FIFO的进程,也会一直阻塞

  • 如果设置了 O_NONBLOCK,以读或写方式打开FIFO会立即返回。返回值会根据有没有相应的写或者读进程提出出错与否。

下面是一段测试代码:

#include <sys/stat.h>
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>

int main()
{
    int ret;
    int fd;
    mode_t mode = 0666;
    if ((ret = mkfifo("./fifo",  mode)) < 0)
    {
        printf("mkfifo error the return code is %s\n", strerror(errno));
        return -1;
    }

    // 测试没有设置O_NONBLOCK标识且写进程不存在,这个操作会一直阻塞
    if ((fd = open("./fifo", O_RDONLY)) < 0)
        printf("open error the return code is %s\n", strerror(errno));
    
    
    // 测试没有设置O_NONBLOCK标识且读进程不存在,这个操作会一直阻塞
    if ((fd = open("./fifo", O_WRONLY)) < 0)
        printf("open error the return code is %s\n", strerror(errno));

    return 0;
}

 

实例

下面是一段利用FIFO实现服务器与客户端通信的例子:

/*
 * file : FIFOread.c
 *
 */


#include <sys/stat.h>
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>

int main()
{
    int ret;
    int fd;
    mode_t mode = 0666;
    if ((ret = mkfifo("./fifo",  mode)) < 0)
    {
        printf("mkfifo error the return code is %s\n", strerror(errno));
        return -1;
    }

    // open the fifo file and papare to read
    if ((fd = open("./fifo", O_RDONLY)) < 0)
    {
        printf("open error the return code is %s\n", strerror(errno));
        return -1;
    }

    // read the data from client and print
    int nRead;
    char line[1024];
    while ((nRead = read(fd, line, 1024)) > 0)
    {
        printf("the recv bytes is %d\n", nRead);
        printf("the recv msg is %s\n", line);
    }

    printf("the return nRead is %d\n", nRead);
    close(fd);
    return 0;
}

 

 

#include <sys/stat.h>
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>

int main()
{
    int fd;
    // open test without O_NOBLOCK flag
    if ((fd = open("./fifo", O_WRONLY)) < 0)
    {
        printf("open error the return code is %s\n", strerror(errno));
        return -1;
    }

    int i;
    int nWrite;
    char line[100] = "Hello FIFO\n";

    for (i = 0; i < 10; i++)
    {
        if ((nWrite = write(fd, line, sizeof(line))) < 0)
        {
            printf("wirte error\n");
            return -1;
        }
        sleep(1);
            
    }
    
    close(fd);
    return 0;
}

 

进程通信——有名管道

标签:

原文地址:http://www.cnblogs.com/Gru--/p/5058662.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!