曲径通幽论坛

 找回密码
 立即注册
搜索
查看: 9916|回复: 1
打印 上一主题 下一主题

[进程] 有名管道的创建与读写

[复制链接]

4918

主题

5880

帖子

3万

积分

GROAD

曲径通幽,安觅芳踪。

Rank: 6Rank: 6

积分
34395
跳转到指定楼层
楼主
发表于 2009-7-24 11:44:42 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
创建有名管道有两种方式:
一是在 shell 下交互地建立一个有名管道,二是在程序中使用系统函数建立有名管道。shell 方式下可使用 mknod 或 mkfifo 命令,下面命令使用 mknod 创建了一个有名管道:
mknod namepipe
创建有名管道的系统函数有两个:mknod() 和 mkfifo() 。两个函数均定义在头文件 sys/stat.h 中,函数原型如下:
#include <sys/types.h>
#include <sys/stat.h>

int mknod(const char *pathname, mode_t mode, dev_t dev);
  int mkfifo(const char *pathname, mode_t mode);
函数 mknod() 参数中path 为创建的有名管道的全路径名;mod 为创建的有名管道的模式,指明其存取权限;dev 为设备值,该值取决于文件创建的种类,它只在创建设备文件时才会用到。这两个函数成功返回 0,失败则返回 -1。
通过查看相关头文件,可以看到 mode_t 是 unsigned int  类型
使用 mknod() 创建一个有名管道
umask(0);
if (mknod ("/tmp/fifo", S_IFIFO | 0666, 0) == -1) {
      perror("mknod error!");
      exit(1);
}

使用 mkfifo() 创建有名管道,mkfifo() 前两个参数的含义和 mknod() 相同
umask(0);
if (mkfifo ("/tmp/fifo", S_IFIFO | 0666, 0) == -1) {
      perror("mkfifo error!");
      exit(1);
}

“S_IFIFO | 0666" 指明创建一个有名管道且存取权限为 0666 ,即创建者、与创建者同组的用户、其他用户对该有名管道的访问权限都是可读可写。

有名管道创建后就可以使用了,有名管道的和管道的使用方法基本相同。只是使用有名管道时,必须先调用 open() 将其打开,因为有名管道是一个存在硬盘上的文件,而管道是存在内存中的特殊文件。

需要注意的是,调用 open() 打开有名管道的进程可能会被阻塞。但如果同时以读写方式 ( O_RDWR ) 打开,则一定不会导致阻塞;如果以只读方式 ( O_RDONLY ) 打开,则调用 open() 函数的进程将会被阻塞直到有写方打开管道;同样以写方式 ( O_WRONLY ) 打开也会阻塞直到有读方打开管道。

4918

主题

5880

帖子

3万

积分

GROAD

曲径通幽,安觅芳踪。

Rank: 6Rank: 6

积分
34395
沙发
 楼主| 发表于 2009-7-24 12:06:07 | 只看该作者

有名管道在无亲缘进程间的通信

两个程序,一写一读,测试有名管道在无亲缘关系的进程间的通信:

读管道程序
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/types.h>

#define    FIFO_NAME    "myfifo"
#define    BUF_SIZE    1024

int main(void)
{
    int     fd;
    char    buf[BUF_SIZE];

    umask(0);
    fd = open(FIFO_NAME, O_RDONLY);
    read(fd, buf, BUF_SIZE);
    printf("Read content: %s\\n", buf);
    close(fd);
    exit(0);
}
写管道程序
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>

#define    FIFO_NAME    "myfifo"
#define    BUF_SIZE    1024

int main(void)
{
    int    fd;
    char    buf[BUF_SIZE] = "Hello procwrite, I come from process named procread!";

    umask(0);

    if (mkfifo(FIFO_NAME, S_IFIFO | 0666) == -1) {
        perror("mkfifo error!");
        exit(1);
    }

    if ((fd = open(FIFO_NAME, O_WRONLY)) == -1) {
        perror("open error!");
        exit(1);
    }

    write(fd, buf, strlen(buf)+1);    /*strlen(buf)+1 是把'\\0'也写过去*/

    close(fd);
    exit(0);
}
运行及输出
编译后,先运行 procwrite.exe ( 运行后处于阻塞状态 )
打开另一个终端运行 procread.exe 程序,输出:
beyes@linux-beyes:~/C/pipe> ./procread.exe
Read content: Hello procwrite, I come from process named procread!
假如不是运行 procread.exe 这个程序,而是直接:
cat myinfo
同样可以看到输出结果,且一旦内容被读出,procwrite.exe 解除阻塞退出。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|曲径通幽 ( 琼ICP备11001422号-1|公安备案:46900502000207 )

GMT+8, 2025-5-4 00:07 , Processed in 0.080658 second(s), 21 queries .

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表