由于命名管道在本地创建了一个管道文件,所以系统调用的IO函数都可以操作命名管道,但是不能使用lseek。
命名管道通过管道文件进行读写操作,例如:open()、write()、read()、close()。和无名管道一样,操作命名管道肯定要考虑默认情况下其阻塞特性。
下面验证的是默认情况下的特点,即 open() 的时候没有指定非阻塞标志( O_NONBLOCK )。
open() 以只读方式打开 FIFO 时,要阻塞到某个进程为写而打开此 FIFO open() 以只写方式打开 FIFO 时,要阻塞到某个进程为读而打开此 FIFO。
简单一句话,只读等着只写,只写等着只读,只有两个都执行到,才会往下执行。
实例:
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/errno.h>
#include <sys/wait.h>
#include <fcntl.h>
#include <string.h>
#define FIFONAME "myfifo"
int main(int argc, char *argv[])
{
int ret;
ret = mkfifo(FIFONAME, 0664); // 创建命名管道
if (ret != 0)
{ // 出错
if (errno != EEXIST)
{
perror("erro to mkfifo:");
//printf("errerno=%d\n",errno); //如果管道已经创建则errno值为17.
exit(1);
}
}
int fd;
fd = open(FIFONAME, O_RDWR);
if (fd == -1)
{
perror("error to open:");
exit(1);
}
if (write(fd, "hello,world!\n", strlen("hello,world!\n")) == -1)
{
perror("error to write:");
exit(1);
}
write(fd, "welcome to linux world!\n", strlen("welcome to linux world!\n"));
char buff[128] = "";
if (read(fd, buff, sizeof(buff)) == -1)
{
perror("error to read:");
exit(1);
}
printf("buff=%s\n",buff);
//再读一次会阻塞
if (read(fd, buff, sizeof(buff)) == -1)
{
perror("error to read:");
exit(1);
}
printf("buff=%s\n",buff);
close(fd);
return 0;
}
运行结果:
[root@iz2zefozq9h39txdb8s7npz shelldemo]# ./a.out
buff=hello,world!
welcome to linux world!