【问题标题】:Select() still blocks read from pipeSelect() 仍然阻止从管道读取
【发布时间】:2013-04-07 00:12:45
【问题描述】:

我的应用程序派生了一个子程序,子程序执行一个新程序,父程序写入它,然后在子程序执行一些工作后从子程序读取。在监控管道的读取端时,程序仍然在等待子进程。我目前没有回信给父母,所以它会故意阻止。下面是代码(write_to()函数关闭了函数中管道中未使用的部分):

    pid_t leaf_proc;


    int rv = 0;

    int w_pfd[2];
    int r_pfd[2];   

    if(pipe(w_pfd) == -1 || pipe(r_pfd) == -1){
        printf("Failed to pipe. Goodbye.\n");
        exit(0);
    }

    if((leaf_proc = fork()) < 0){
        printf("Error: %s\n",strerror(errno));
        exit(0);
    }else if(leaf_proc == 0){
        /***Child to be execl()'d***/
        rv = execl("Some program");
        if(rv < 0){
            printf("Error: %s\n",strerror(errno));
            exit(0);
        }
    }else{
        /***Parent***/
        write_to(par_info,w_pfd);
        fd_set read_set;
        //struct timeval tv;
        //tv.tv_sec = 5;
        //tv.tv_usec = 0;

        FD_ZERO(&read_set);
        FD_SET(r_pfd[0], &read_set);
        rv = select(r_pfd[0]+1,&read_set,NULL,NULL,&tv);
        printf("set?: %d\n",rv);
     }

运行此程序时,程序仍会在 select 语句处挂起(永远不会到达最后一个 printf),但如果我添加超时信息,程序会在 5 秒后继续。首先,我是否正确使用 select ?其次,虽然这可能不会阻塞(从某种意义上说,父进程不会被内核中断,但它是否仍然会导致结果(进程挂起,直到准备好)?

【问题讨论】:

  • 首先,您需要制作&amp;read_set 的主副本,因为如果您阅读select() 上的手册,您会看到它修改了FD 列表。

标签: c io fork ipc pipe


【解决方案1】:

您必须在子进程和父进程中关闭管道的未使用部分。

终止后管道的写fd会在子进程中关闭,但在父进程中仍然是打开的,所以你的select会耐心等待数据......

【讨论】:

  • 对不起,不清楚,但 write_to() 函数负责关闭管道的读取端,子进程中的 write_to 函数也是如此。如果 select 等待数据,这本质上是不是阻塞,而不是让进程进入睡眠状态?
  • 1) 子进程中没有write_to.... 2) 就像休眠一样,同时select块,进程不会占用CPU。
  • 子进程execl是一个调用write_to的程序
  • 您是否关闭了父级管道的写入端?
  • 是的,我已经编写了名为 write_to() 和 read_from() 的函数来处理关闭管道的正确端。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-06-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多