【问题标题】:C child read giving "resource temporarily unavailable"C子读给“资源暂时不可用”
【发布时间】:2010-05-05 02:18:35
【问题描述】:

所以我有一个从父进程到子进程的文件流——而且大多数时候它工作正常。但是,当多次快速读取时,使用 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);

} 

【问题讨论】:

  • 打开管道并创建子进程的代码更有可能有帮助。
  • fpin是怎么打开的?包括那些(PARENT|CHILD)_(READ|WRITE) 的定义也可能会有所帮助。
  • 它是用 fopen(PARENT_READ, "r");其中 PARENT_READ 是父用于读取的管道一侧的宏

标签: c process fgets


【解决方案1】:

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

(Resource暂时不可用EAGAIN/EWOULDBLOCK对应的错误信息,只有在选择了非阻塞IO且没有数据到时read()才会返回阅读)。

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

进一步调查的一些想法:

  • 如果你strace()子进程,哪个系统调用返回EAGAIN?在哪个文件描述符上?

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

【讨论】:

  • 否,stdin 尚未设置为非阻塞。如果它有帮助,它似乎会等待与 select 语句超时相同的时间,然后再给出错误。我现在将发布一些代码..
  • 嗯,该错误消息仅由read() 为非阻塞文件描述符返回 - 我已经更新了我的答案,并提供了一些进一步的调查想法......
  • 我不认为我可以使用 strace,因为我在 Mac 上。如果可以,你能解释一下怎么做吗?此外,第二条语句总是返回 2(但在这种情况下文件流不是标准输入)。另外,什么可能导致 fgets() 返回 NULL 但 feof(stream) 会返回 false?这就是当我没有遇到“资源暂时不可用”问题时会发生的情况
  • dtruss 在 OS X(Leopard 和更高版本,无论如何)上提供等效功能。父级关闭了哪些管道?
  • 父级关闭子级的读写管道,我会研究dtruss。谢谢
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-11-21
  • 2021-02-21
  • 2018-08-04
  • 2021-05-07
  • 2018-02-24
  • 2016-01-25
  • 2012-04-25
相关资源
最近更新 更多