我对未命名的烟斗或" fifos"有一些问题。在C.我有两个可执行文件:一个尝试读取,另一个尝试写入。读者只能执行一次。我试着制作一个简单的代码来显示我的问题,所以它会读取10次然后关闭。但是,作者应该被执行多次(在我的原始程序中,它不能一次执行两次:你必须等待它再次运行它。)
此代码的问题是:它仅在另一个消息到达时打印传入消息。它似乎被阻止,直到收到另一条消息。我不知道发生了什么,但似乎是"阅读"尽管有数据要读取,但是行阻止程序,当我发送新数据时,它会再次起作用。
我尝试了另一件事:你可以看到编写器关闭了文件描述符。阅读器打开文件描述符两次,因为它会找到EOF并且如果它没有被取消阻止。我尝试消除这些线条(作者不会关闭fd,读者只会打开fd一次,消除第二个" open()")。但出于某种原因,如果我这样做,它会解除阻碍。为什么会这样?
这是我的代码:
阅读器:
int main () {
int fd;
static const std::string FILE_FIFO = "/tmp/archivo_fifo";
mknod ( static_cast<const char*>(FILE_FIFO.c_str()),S_IFIFO|0666,0 );
std::string mess = "Hii!! Example";
//open:
fd = open ( static_cast<const char*>(FILE_FIFO.c_str()),O_WRONLY );
//write:
write ( fd, static_cast<const void*>(mess.c_str()) ,mess.length() );
std::cout << "[Writer] I wrote " << mess << std::endl;
//close:
close ( fd );
fd = -1;
std::cout << "[Writer] END" << std::endl;
exit ( 0 );
}
编剧:
int main () {
int i,fd;
static const int BUFFSIZE = 100;
static const std::string name = "/tmp/archivo_fifo";
mknod ( static_cast<const char*>(name.c_str()),S_IFIFO|0666,0 );
char buffer[BUFFSIZE];
i=0;
fd = open ( name.c_str(),O_RDONLY );
while (true) {
i++;
std::cout << "Waiting to read Fifo: "<< i << std::endl;
ssize_t bytesLeidos = read ( fd,static_cast<void*>(buffer),BUFFSIZE);
fd = open ( name.c_str(),O_RDONLY );
std::string mess = buffer;
mess.resize ( bytesLeidos );
std::cout << "[Reader] I read: " << mess << std::endl;
sleep(3);
if (i==10) break;
}
close ( fd );
fd = -1;
unlink ( name.c_str() );
std::cout << "[Reader] END" << std::endl;
exit ( 0 );
}
提前致谢。请原谅我可怜的英语
答案 0 :(得分:0)
答案 1 :(得分:0)
您已在blocking mode中打开文件:
如果某个进程打开了管道并且O_NONBLOCK已清除,则read()将阻塞调用线程,直到写入一些数据或管道被管道打开以供写入的所有进程关闭。
取决于您的目标,您应该与管道的读者和作者同步,或者为读者使用非阻止模式。阅读poll, epoll, select。
答案 2 :(得分:0)
我一直在阅读更多有关未命名管道的信息,现在我明白了这个问题。我写道:
阅读器打开文件描述符两次,因为它会找到EOF并且如果没有则会被取消阻止。我尝试消除那些行(作者不会关闭fd,读者只会打开fd一次,消除第二个“open()”)。但出于某种原因,如果我这样做,它会解除阻碍。为什么会这样?
它取消阻止,因为其他进程关闭,因此操作系统无论如何都会关闭文件描述符。这就是为什么虽然我没有写关闭(fd)它解除阻塞。
阻止fifo可以取消阻止的唯一方法是:
1)有数据需要阅读 2)其他程序关闭文件描述符。如果没有要读取的数据且编写器关闭了文件描述符(即使文件描述符在阅读器中打开),read()也会返回0并取消阻塞。
所以我的解决方案是:重新设计我的程序,这样就可以让编写器的文件描述符一直打开。这意味着:现在只有一个可执行文件。我很确定我可以使用两个可执行文件来完成它,但我可能需要信号量或类似的东西来进行同步,因此如果编写器的fd已关闭,它就不会尝试读取。