fork之后关闭的描述符是否会在其他进程中无效?

web*_*ius 2 c sockets

我在这个链接中引用了以下代码片段:

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");
}
Run Code Online (Sandbox Code Playgroud)

fork()调用之后,会有两个进程 - Parent和child.

对于父进程,else部分保持为true,因此它将关闭newsockfd.但是,子进程使用newsockfd在dostuff方法中读写系统调用.在这种情况下,读写系统调用是否会失败?

Raf*_*cki 8

不,因为在fork复制所有打开的文件描述符并且它们不是相同的描述符时,它们只指向同一个文件.

fork(2)联机帮助页:

子进程继承父进程打开文件描述符的副本.子节点中的每个文件描述符引用相同的打开文件描述(请参阅open(2))作为父节点中的相应文件描述符.这意味着两个描述符共享打开文件状态标志,当前文件偏移和信号驱动的I/O属性(请参阅fcntl(2)中的F_SETOWN和F_SETSIG的描述).

  • 如果关闭对该端点的最后一个引用,则"close"仅关闭通信端点.在这种情况下,另一个进程也保存对该端点的引用.所以`close`只释放那个进程'的引用. (5认同)
  • 你错过了,David Schwartz所说的 - 如果它关闭了对该端点的最后一个引用,那么`close`会关闭一个通信端点.如果存在任何其他引用(另一个描述符),则不会关闭端点本身. (2认同)
  • 在使用`exit(0)`终止执行后,描述符被关闭.我必须承认,这不是最好的主意,但让这个例子变得简单(可能太简单了). (2认同)