【问题标题】:Will the descriptors closed after fork be invalid in the other process?fork后关闭的descriptor在其他进程中会失效吗?
【发布时间】:2012-04-27 22:22:17
【问题描述】:

我指的是link中的以下代码sn-p:

while (1)
 {
   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);
     dostuff(newsockfd);
     exit(0);
   }
   else
     close(newsockfd);
 } /* end of while */

void dostuff (int sock)
{
   int n;
   char buffer[256];

   bzero(buffer,256);
   n = read(sock,buffer,255);
   if (n < 0) error("ERROR reading from socket");
   printf("Here is the message: %s\n",buffer);
   n = write(sock,"I got your message",18);
   if (n < 0) error("ERROR writing to socket");
}

在 fork() 调用之后,会有两个进程 - 父进程和子进程。

对于父进程,else部分成立,所以它会关闭newsockfd。但是newsockfd被子进程用于dostuff方法中的读写系统调用。这种情况下读写系统调用会不会失败?

【问题讨论】:

  • 孩子不应该打电话给exit(0),而应该打电话给_exit(0)。否则,您将在调用 fork 时存在的任何流刷新两次。在这个例子中没关系,但为更实际的案例树立了一个很好的例子。
  • 一旦fork()返回,两个进程是分开的;它们有单独的描述符副本,指向同一个打开的文件描述。一个进程中的关闭根本不会影响另一个进程(也许除了使另一个进程成为打开文件描述的唯一所有者之外)。文件描述符和打开文件描述的区别见POSIX open();还有dup2()fork()

标签: c sockets


【解决方案1】:

不,因为在fork 期间,所有打开的文件描述符都会被复制,而且它们不是同一个描述符,它们只是指向同一个文件。

来自fork(2) manpage

子继承父打开文件集的副本 描述符。 child 中的每个文件描述符都指向同一个 open 文件描述(参见 open(2))作为对应的文件描述符 父母。这意味着两个描述符共享打开文件状态 标志、当前文件偏移量和信号驱动的 I/O 属性(请参阅 fcntl(2)中对F_SETOWN和F_SETSIG的描述。

【讨论】:

  • A close 仅在关闭对该端点的最后一个引用时才关闭该通信端点。在这种情况下,另一个进程也持有对该端点的引用。所以close 只发布该进程的引用。
  • 同意子进程将拥有一份newsockfd的副本。但是父进程和子进程中的 newsockfd 都将指向同一个客户端套接字。所以父进程将关闭它。我在这里错过了什么吗?
  • 您错过了,David Schwartz 所说的 - close 如果关闭对该端点的最后一个引用,则会关闭该端点。如果存在任何其他引用(其他描述符),则端点本身不会关闭。
  • 知道了。非常感谢 David 和 Rafal 的快速回复。
  • 描述符在使用exit(0) 终止执行后关闭。我必须承认,这不是最好的主意,但会使示例变得简单(可能太简单了)。
【解决方案2】:

子进程将在自己的内存中拥有自己全新的“newsockfd”。那里的套接字句柄与正在关闭的父级“newsockfd”没有任何共同之处。

【讨论】:

  • 直到关闭点,两组文件描述符共享相同的打开文件描述(因此它们有共同点;每个进程中的编号也相同),但你是对的在一个进程中关闭文件对另一个进程中的相应文件描述符没有影响。
猜你喜欢
  • 2011-01-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-10-06
  • 2014-02-11
  • 2013-10-22
  • 2012-04-04
  • 1970-01-01
相关资源
最近更新 更多