C语言子进程读取时出现"资源暂时不可用"错误提示。

9
所以我有一个来自父进程到子进程的文件流,并且大多数情况下它都正常工作。然而,当快速多次从中读取时,使用fgets()将返回NULL并设置错误为“资源暂时不可用”。问题是不定期的,运行进行读取的脚本有时会使fgets返回NULL,有时则不会。
有人能帮我停止这个错误吗?谢谢!
编辑:这是一些代码..我不确定什么其他代码会有帮助?有相当多的代码。
// this is the bit that gets a line from the child
if( fgets( line, MAX_LINE_LENGTH, fpin ) == NULL ) {
    if( ferror(fpin) ) {
        perror("error on stream fpin");
    }
    free( line );
    return FAIL;
}

按照要求,以下是打开管道并处理子进程的代码。

// set up pipes
int readPipe[2]; // child -> parent communication
int writePipe[2]; // parent -> child communication
int errorPipe[2]; // child -> parent, to check for errors in exec

/* create pipe */
pipe( readPipe ); // error if return val < 1 for any
pipe( writePipe );
pipe( errorPipe );
pid_t pid; /* process id when we fork */
pid = fork(); /* create new child */

if( pid == 0 ) { /* pid == 0 indicates child process */

    // close unused fds
    close( PARENT_READ );
    close( PARENT_WRITE );
    close( errorPipe[0] );

    dup2( CHILD_READ, 0 ); // replace stdin with pipe in
    dup2( CHILD_WRITE, 1 ); // replace stdout with pipe out

    /* replace child process with program to run */
    execvp(args[0], args);

    // if we get here, exec failed so inform the parent
    char *error_message = "exec failed";
    write( errorPipe[1], error_message, strlen(error_message)+1 );
    exit(-1);

} 

打开管道并创建子进程的代码更有可能是有用的。 - caf
fpin 是如何打开的?包括那些 (PARENT|CHILD)_(READ|WRITE) 的定义也可能有所帮助。 - caf
它使用fopen(PARENT_READ, "r")打开,其中PARENT_READ是父进程用于读取管道的一侧的宏。 - Gary
1个回答

14

这意味着有人将标准输入文件描述符设置为非阻塞。

("Resource temporarily unavailable"是与EAGAIN/EWOULDBLOCK相对应的错误消息,仅当选择非阻塞IO并且没有数据可读时,read()才会返回该消息)。

请注意,在执行子进程之前,父进程可能已将文件描述符设置为非阻塞状态。

进一步调查的一些想法:

  • 如果您使用strace()追踪子进程,哪个系统调用会返回EAGAIN?在哪个文件描述符编号上?

  • 在失败的fgets()之前,printf("%d\n", fcntl(fileno(fpin), F_GETFL))的输出是什么?


不,stdin没有被设置为非阻塞。如果有帮助的话,它似乎会等待与我下面进一步选择语句的超时时间相同的时间,然后才会出现错误。我现在会发布一些代码。 - Gary
那个错误信息只有在非阻塞文件描述符上才会被read()返回 - 我已经更新了我的答案,并提供了一些进一步的调查思路... - caf
我不认为我可以在Mac上使用strace。如果可以的话,你能解释一下怎么做吗?此外,第二个语句总是返回2(但在这种情况下文件流不是stdin)。此外,什么可能导致fgets()返回NULL,但feof(stream)返回false?当我没有遇到“资源暂时不可用”的问题时,就会发生这种情况。 - Gary
dtruss 在 OS X 上提供了相同的功能(至少在 Leopard 及以后版本)。父进程关闭哪些管道? - caf
父进程关闭子进程的读写管道,我会查看dtruss。谢谢。 - Gary

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接