阅读封闭的命名管道块
Read on closed named pipe blocks
我正在尝试使用 Fortran 从命名管道 (FIFO) 读取数据。读取数据有效,但 Fortran 程序似乎没有注意到另一端的管道何时关闭;读取只是阻塞而不是获取 EOF。
示例程序:
program kitten
character(256) :: buf
open(22, file='test')
do
read(22, *) buf
print*, trim(buf)
end do
end program kitten
现在
$ mkfifo test
$ echo -e '1\n2\n3' >test &
$ ./kitten
程序按预期打印 1\n2\n3\n
,但随后挂起。
相反,如果
,程序 returns EOF 错误
test
是普通文件;或
- 您将
kitten
更改为从 STDIN 读取并执行 ./kitten <test
或
echo -e '1\n2\n3' | ./kitten
;或
- 你用 C 写了一个等效的
kitten
程序。
我用 ifort 15.0.1
和 gfortran 4.9.2
测试了这个,结果相同。
对于 C,我使用了 gcc
和
#include <stdio.h>
main() {
char buf[256];
FILE *test;
test = fopen("test", "r");
while(fgets(buf, 256, test)) {
printf(buf);
}
}
我对 Fortran 了解不多,但我知道您可以通过在打开中使用 read/write 模式(例如 fopen("test", "r+")
在管道上的可写文件描述符的数量下降到 0 之前,管道不会获得 EOF。当您的读取文件描述符也可写时,您永远不会获得 EOF。
所以我的猜测是 fortran 默认以 read/write 模式打开,您需要告诉它不要那样做。 This question about a fortran readonly flag 可能会有帮助。
关于 C 程序。
更好的版本是:
#include <stdio.h>
#include <stdlib.h> // exit(), EXIT_FAILURE
int main( void ) // properly declare main()
{
char buf[256];
FILE * test = NULL;
if( NULL == (test = fopen("test", "r") ) ) // check for open error
{ // then fopen failed
perror( "fopen for test for read failed");
exit( EXIT_FAILURE );
}
// implied else, fopen successful
while(fgets(buf, 256, test) ) // exit loop when fgets encounters EOF
{
printf("%s\n",buf);
}
fclose( test ); // cleanup before exiting
return 0; // properly supply a return value
}
我正在尝试使用 Fortran 从命名管道 (FIFO) 读取数据。读取数据有效,但 Fortran 程序似乎没有注意到另一端的管道何时关闭;读取只是阻塞而不是获取 EOF。
示例程序:
program kitten
character(256) :: buf
open(22, file='test')
do
read(22, *) buf
print*, trim(buf)
end do
end program kitten
现在
$ mkfifo test
$ echo -e '1\n2\n3' >test &
$ ./kitten
程序按预期打印 1\n2\n3\n
,但随后挂起。
相反,如果
,程序 returns EOF 错误test
是普通文件;或- 您将
kitten
更改为从 STDIN 读取并执行./kitten <test
或 echo -e '1\n2\n3' | ./kitten
;或- 你用 C 写了一个等效的
kitten
程序。
我用 ifort 15.0.1
和 gfortran 4.9.2
测试了这个,结果相同。
对于 C,我使用了 gcc
和
#include <stdio.h>
main() {
char buf[256];
FILE *test;
test = fopen("test", "r");
while(fgets(buf, 256, test)) {
printf(buf);
}
}
我对 Fortran 了解不多,但我知道您可以通过在打开中使用 read/write 模式(例如 fopen("test", "r+")
在管道上的可写文件描述符的数量下降到 0 之前,管道不会获得 EOF。当您的读取文件描述符也可写时,您永远不会获得 EOF。
所以我的猜测是 fortran 默认以 read/write 模式打开,您需要告诉它不要那样做。 This question about a fortran readonly flag 可能会有帮助。
关于 C 程序。
更好的版本是:
#include <stdio.h>
#include <stdlib.h> // exit(), EXIT_FAILURE
int main( void ) // properly declare main()
{
char buf[256];
FILE * test = NULL;
if( NULL == (test = fopen("test", "r") ) ) // check for open error
{ // then fopen failed
perror( "fopen for test for read failed");
exit( EXIT_FAILURE );
}
// implied else, fopen successful
while(fgets(buf, 256, test) ) // exit loop when fgets encounters EOF
{
printf("%s\n",buf);
}
fclose( test ); // cleanup before exiting
return 0; // properly supply a return value
}