fifo中阻塞的问题,与文件的差别

来源:互联网 发布:jquery 2.1.0.min.js 编辑:程序博客网 时间:2024/05/16 15:31

本文掺靠: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_SIZE1024

 

int main(void)

{

intwfd, rfd;

charbuf[BUF_SIZE];

intlen;

 

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_SIZE1024

 

int main(void)

{

intwfd, rfd;

    charbuf[BUF_SIZE];

intlen;

 

   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));

    }

}

原创粉丝点击