本文掺靠:http://hi.baidu.com/kwokwing0011/blog/item/0b63afee86976b3763d09f36.html
有名管道的打开规则
有名管道比管道多了一个打开操作:open。
FIFO的打开规则:
如果当前打开操作是为读而打开FIFO时,若已经有相应进程为写而打开该FIFO,则当前打开操作将成功返回;否则,可能阻塞直到有相应进程为写而打开该FIFO(当前打开操作设置了阻塞标志);或者,成功返回(当前打开操作没有设置阻塞标志)。
如果当前打开操作是为写而打开FIFO时,如果已经有相应进程为读而打开该FIFO,则当前打开操作将成功返回;否则,可能阻塞直到有相应进程为读而打开该FIFO(当前打开操作设置了阻塞标志);或者,返回ENXIO错误(当前打开操作没有设置阻塞标志)。
注意:
读取管道打开时需要等待写入管道的打开,同时写入打开管道又需要等待读取管道的打开
Deadlock不会产生,因为这里“等待”的*不*是另一方的open是否*已经完成*
举个例子,
如果open FIFO时都不指定O_NONBLOCK, A进程首先 open FIFO for reading, 它会block.
然后B进程 open FIFO for writing, 由于进程A正在open for reading, 因此B的open操作会
立即返回,然后A的open 操作返回。
文件的打开open没有阻塞发生。。。
下面是两个例子:
server.c服务器端
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#define FIFO_READ "/tmp/readfifo"
#define FIFO_WRITE "/tmp/writefifo"
#define BUF_SIZE 1024
int main(void)
{
int wfd, rfd;
char buf[BUF_SIZE];
int len;
umask(0);
if(access(FIFO_WRITE,F_OK) == -1)
{
if(mkfifo (FIFO_WRITE, S_IFIFO|0666)) {
printf ("Can't create FIFO %s because %s", FIFO_WRITE, strerror(errno));
exit (1);
}
}
umask(0);
printf("/tmp/writefifo open before/n");
wfd = open(FIFO_WRITE, O_WRONLY);//打开时会阻塞,等待client端相应的打开。才可以继续。。但是用O_RDWR就没有这回是
printf("/tmp/writefifo open after/n");
if (wfd == -1) {
printf("open FIFO %s error: %s", FIFO_WRITE, strerror(errno));
exit(1);
}
//sleep(4);
printf("/tmp/readfifo open before/n");
while ((rfd = open(FIFO_READ, O_RDONLY)) == -1) {
sleep(1);
}
printf("/tmp/readfifo open after/n");
while (1)
{
printf ("Server: ");
fgets (buf, BUF_SIZE, stdin);
buf[strlen(buf)-1] = '/0';
if (strncmp (buf,"quit", 4) == 0) {
close (wfd);
unlink (FIFO_WRITE);
close (rfd);
exit (0);
}
write (wfd, buf, strlen(buf));
len = read (rfd, buf, BUF_SIZE);
if ( len > 0) {
buf[len] = '/0';
printf ("Client: %s/n", buf);
}
}
}
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
#include <stdio.h>
#include <errno.h>
#include <fcntl.h>
# define FIFO_READ "/tmp/writefifo"
# define FIFO_WRITE "/tmp/readfifo"
#define BUF_SIZE 1024
int main(void)
{
int wfd, rfd;
char buf[BUF_SIZE];
int len;
umask(0);
if(access(FIFO_WRITE,F_OK) == -1)
{ if(mkfifo (FIFO_WRITE, S_IFIFO|0666))
{
printf ("Can't create FIFO %s because %s", FIFO_WRITE, strerror(errno));
//exit(1);
}
}
printf("/tmp/writefifo open before/n");
while ((rfd = open(FIFO_READ, O_RDONLY)) == -1)
{
sleep(1);
}
printf("/tmp/writefifo open after/n");
sleep(8);
printf("/tmp/readfifo open before/n");
wfd = open(FIFO_WRITE, O_WRONLY);
printf("/tmp/readfifo open after/n");
if (wfd == -1)
{
printf("Fail to open FIFO %s: %s", FIFO_WRITE, strerror(errno));
exit(-1);
}
while (1)
{
len = read(rfd, buf, BUF_SIZE);
if ( len > 0) {
buf[len] = '/0';
printf("Server: %s/n", buf);
}
printf("Client: ");
fgets(buf, BUF_SIZE, stdin);
buf[strlen(buf) -1] = '/0';
if (strncmp(buf,"quit", 4) == 0) {
close (wfd);
unlink (FIFO_WRITE);
close (rfd);
exit (0);
}
write (wfd, buf, strlen(buf));
}
}