在命名管道中使用 open 函数

Posted

技术标签:

【中文标题】在命名管道中使用 open 函数【英文标题】:Using the open function in named pipes 【发布时间】:2016-03-17 09:25:23 【问题描述】:

我有两个进程。 先读后写。 其他人会先写然后读。 我想用两个管道来实现它。

这是我的实现

/***READ BEFORE WRITE*****/
#include <fcntl.h>
#include <stdio.h>
#include <sys/stat.h>
#include <unistd.h>
#define MAX_BUF 1024

int main()

 int fd,fd1;
 char buf[MAX_BUF];
 char * myfifo = "/home/aditya/Desktop/myfifo";
 char * mynewfifo = "/home/aditya/Desktop/mynewfifo";

 mkfifo(mynewfifo, 0666);

 printf("Read before writing\n");   
 printf("Before opening\n");

 fd = open(myfifo, O_RDONLY);
 fd1 = open(mynewfifo, O_WRONLY);
 printf("After opening\n");


 read(fd, buf, MAX_BUF);
 printf("Received: %s\n", buf);
 close(fd);

 printf("reader is writing\n"); 
 write(fd1, "Hi", sizeof("Hi"));
 close(fd1);    

unlink(mynewfifo);  

return 0;



/**** Wriiting after Reading ******/              
#include <fcntl.h>
#include <stdio.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

int main()

 int fd,fd1;
 char * myfifo = "/home/aditya/Desktop/myfifo";
 char * mynewfifo = "/home/aditya/Desktop/mynewfifo";
 char buf[1024];    

 mkfifo(myfifo, 0666);

 printf("writing before reading\n");

 printf("Before opening\n");

 fd = open(myfifo, O_WRONLY);
 fd1=open(mynewfifo,O_RDONLY);  
 printf("After opening\n");

 write(fd, "Hi", sizeof("Hi"));
 close(fd);

 printf("Writer is reading\n"); 
 read(fd1, buf, 1024);
 printf("Received: %s\n", buf);
 close(fd1);

/* remove the FIFO */
unlink(myfifo);

return 0;

当我先运行“读后写”然后“写后读”时,它似乎工作。 但是当我反之亦然(即运行“写入后读取”)时,它们会打印“打开前”并继续运行。

请解释我做错了什么。

【问题讨论】:

【参考方案1】:

问题是您的 READ AFTER WRITE 程序从尚未创建的命名管道 myfifo 读取。当您首先尝试执行 READ AFTER WRITE 程序时。我在您的程序中添加了以下两个条件(请参见下面的代码),以检查您的名称管道中是否存在问题,并且在您第一次执行 READ AFTER WRITE 程序时确实弹出了一个问题,即您的 myfifo 管道未创建。

现在发生的情况是,由于未创建管道,因此您的 READ AFTER WRITE 一直在等待其他一些进程写入,以便可以读取某些内容。另外,另一方面,您的第二个程序也一直处于“正在打开...”,因为另一方面没有阅读器来阅读它应该写的内容。

现在,当您首先执行第二个程序时,这个问题得到解决,因为已经创建了 myfifo 管道以供 READ AFTER WRITE 程序读取。这是真正合乎逻辑的,因为您试图从创建于你的第二个程序。

因此,请务必在您的程序中检查您正在使用的管道是否已创建。

/***READ AFTER WRITE*****/
#include <fcntl.h>
#include <stdio.h>
#include <sys/stat.h>
#include <unistd.h>
#define MAX_BUF 1024

int main()

 int fd,fd1;
 char buf[MAX_BUF];
 char * myfifo = "/home/aisha/Desktop/myfifo";
 char * mynewfifo = "/home/aisha/Desktop/mynewfifo";

 mkfifo(mynewfifo, 0666);

 printf("Read before writing\n");   
 printf("Before opening\n");

 fd = open(myfifo, O_RDONLY);
 if(fd<0)
 
    printf("MYFIFO NOT MADE\n");
 
 fd1 = open(mynewfifo, O_WRONLY);
 if(fd1<0)
 
    printf("MYNEWFIFO NOT MADE\n");
 

 sleep (2);
 printf("After opening\n");

 read(fd, buf, MAX_BUF);
 printf("Received: %s\n", buf);
 close(fd);

 printf("reader is writing\n"); 
 write(fd1, "Hi", sizeof("Hi"));
 close(fd1);    

unlink(mynewfifo);  


return 0;

【讨论】:

如果您创建一个仅包含创建管道代码的单独文件,您的问题可以轻松解决。始终首先运行此文件,这样您就不会遇到任何“未创建管道”问题,然后由您决定是先运行 READ AFTER WRITE 还是另一个。希望这会有所帮助!

以上是关于在命名管道中使用 open 函数的主要内容,如果未能解决你的问题,请参考以下文章

命名管道FIFO

命名管道卡在打开状态

如何在 perl 中读/写命名管道?

c中的命名管道

如何阻止在 Ruby 中读取命名管道?

Linux:打开命名管道进行写入时超时