【问题标题】:Parent and child process, socket close父子进程,socket关闭
【发布时间】:2011-02-27 14:54:50
【问题描述】:

我被这段模拟服务器-客户端交互的代码 sn-p 卡住了,假设 sockfd 是在服务器端创建的套接字文件描述符。

我的问题是,当父进程和它的子进程“同时”运行时,在子进程的执行时间片中,它关闭了服务器套接字 sockfd,然后当执行流到,比如说,第二次循环,调用accpet函数,那里的参数sockfd是否有效,是否被子进程关闭,即从内核文件描述符表中解除分配?

while (1) {
    //accept a connection from client,get the new socket from client
                       //is the sockfd valid here,is it closed by the child in
                       //the previous loop
     newsockfd = accept(sockfd,(struct sockaddr *) &cli_addr, &clilen); 

     if (newsockfd < 0) 
         error("ERROR on accept");
     pid = fork();
     if (pid < 0)
         error("ERROR on fork");
     if (pid == 0)  {
         close(sockfd);  // can't this cause problem ??
         dostuff(newsockfd);
         exit(0);
     }
     else close(newsockfd);
 } /* end of while */

【问题讨论】:

    标签: sockets process parent-child


    【解决方案1】:

    在这段代码中:

    if (pid == 0)  {
         close(sockfd);  // can't this cause problem ??
         dostuff(newsockfd);
         exit(0);
     }
    

    close() 仅影响子级的 sockfd 文件描述符副本。

    父母的副本仍处于打开状态,以供下次循环使用。

    子进程关闭不需要的继承文件描述符被认为是一种很好的方式。

    【讨论】:

    • 谢谢。但如果我没有误解,内核文件描述符表只有一个实例,一旦孩子关闭 sockfd(它就像内核 fd 表的索引),fd 被释放,然后下次父尝试使用它,会不会有问题?
    • 不,每个进程都有自己的 fd 表,从 stdin == 0 等开始。内核只有在 no 进程打开套接字时才放开套接字。
    【解决方案2】:

    父级所做的任何事情都不会导致子文件描述符按照您的意思关闭。对它的操作将根据情况返回适当的状态,但在子进程调用close之前,opendup 永远不会返回该数字。

    【讨论】:

    • 嗨,我似乎看不到子文件描述符。我错过了什么吗?我只是怀疑孩子关闭需要在下一个循环中使用的 fd 是否会导致问题。请查看我的最后编辑。谢谢!
    【解决方案3】:

    每当您调用fork() 函数时,子进程都会复制当前进程。因此在第二个循环中,子进程中的sockfd 与父进程相同(尚未关闭)。所以它是有效的。

    【讨论】:

    • 请查看我对问题的最后编辑。我的意思是传递给接受函数的 sockfd 是否有效,它是否被前一个循环中的子进程关闭。
    【解决方案4】:

    看来,当您关闭重复的 fd 时,它并没有真正关闭流,直到所有都关闭。我用我创建的一个有趣的网络服务器遇到了这个问题。我关闭了 fork 中的 fd,但它保持打开状态。

    我通过在 fork 之后在父级中关闭它来修复它。

    【讨论】:

      猜你喜欢
      • 2018-06-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-04-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多