使用命名管道的操作和使用普通的文本文件类似,都是系统调用open函数去打开创建好的管道,使用read,write函数操作,操作完成后用close函数关闭。
从FIFO中读取数据的规则是:
1,如果一个进程为了从fifo中读取数据而阻塞打开fifo,n那么称该进程内的读操作为设置了阻塞标志的读操作。
2,如果有进程写打开了fifo,而且当前fifo内没有数据,则对于这于设置了阻塞标志的读操作来说,将一直阻塞,对于没有设置阻塞标志读操作来说则返回-1,当前errno值为EGIN,提醒以后再试。
3,对于设置阻塞标志的读操作来说,造成阻塞的原因有两种:① 当前fifo内有数据,但有其他的进程在读这些数据。②fifo里面没有数据。解阻塞的原因则是fifo有新的数据写入不管新写入数据量的大小,也不论读操作请求多少数据。
4,读打开的阻塞标志只对本进程第一个读操作施加作用,如果本进程内有多个读操作序列,则在第一个读操作被唤醒并完成读操作后,其他要执行的读操作将不再阻塞。即使在执行读操作时,fifo里面没有数据也一样(读操作返回0)。
5,如果没有写进程打开fifo,则设置了阻塞标志的读操作也会阻塞。
向fifo中写入数据的规则是:
1.如果一个进程为了向fifo中写数据而阻塞打开fifo,那么称该进程内的写操作为设置了阻塞标志的写操作。
2.对于设置了阻塞标志的写操作,当要写入的数据量不大于PIPE_BUF时,Linux将保证写入的原子性,如果此时管道空闲缓冲区不足以容纳要写入的数据时,则进入睡眠,知道当缓冲区能够容下要写入数据字节数时,才开始进行一次性写操作。
3.当要写入的数据量大于PIPE_BUF时,linux不能保证写入的原子性,在写满fifo空闲缓冲区后,写操作返回。
4.要写入的数据量不大于PIPE_BUF时,linux将保证写入原子性,如果当前缓冲区能容下要写的数据,则写完后返回,相反的话,返回EAGIN错误,提醒以后再写。
-
write_fifo.c:
-
-
#include<sys/types.h>
-
#include<sys/stat.h>
-
#include<stdio.h>
-
#include<fcntl.h>
-
#include<unistd.h>
-
#include<limits.h>
-
#include<stdlib.h>
-
#include<time.h>
-
#define BUFES PIPE_BUF
-
int main(void)
-
{
-
int fd;
-
int n,i;
-
char buf[BUFES];
-
time_t tp;
-
printf(
"%d\n",getpid());
-
if((fd=open(
"fifo1",O_WRONLY))<
0)
-
{
-
printf(
"open failed\n");
-
exit(
1);
-
}
-
for(i=
0;i<
10;i++)
-
{
-
time(&tp);
-
n=
sprintf(buf,
"write fifo %d sends %s",getpid(),ctime(&tp));
-
printf(
"send msg:%s\n",buf);
-
if((write(fd,buf,n+
1))<
0)
-
{
-
printf(
"write failed!\n");
-
close(fd);
-
exit(
1);
-
}
-
sleep(
3);
-
}
-
close(fd);
-
exit(
0);
-
}
-
read_fifo.c
-
-
#include<sys/types.h>
-
#include<sys/stat.h>
-
#include<unistd.h>
-
#include<stdlib.h>
-
#include<stdio.h>
-
#include<limits.h>
-
#include<fcntl.h>
-
#define BUFES PIPE_BUF
-
int main(void)
-
{
-
int fd;
-
int len;
-
char buf[BUFES];
-
mode_t mode =
0666;
-
if((fd=open(
"fifo1",O_RDONLY))<
0)
-
{
-
printf(
"Open failed");
-
exit(
1);
-
}
-
while((len=read(fd,buf,BUFES))>
0)
-
{
-
printf(
"Read_fifo read:%s\n",buf);
-
}
-
close(fd);
-
exit(
0);
-
return
0;
-
}
Step 1: lishun@lishun-Qt:~$ mkfifo -m 0666 fifo1 (建立管道)
Step2: gcc write_fifo.c -o write
Ste2: ./write (write 当前 阻塞,一直到运行read)
Step3: gcc read_fifo.c -o read
Step4: ./read