儿童父母关系与继承

时间:2011-02-16 19:41:07

标签: c fork

我对C来说是全新的。

  1. 使用fork();创建的子项中继承的进程项有哪些?

  2. 与流程的父级不同的流程项是什么?

5 个答案:

答案 0 :(得分:15)

这与C没什么关系,而是与fork()有关,这是一个POSIX系统调用(我猜它在不同系统上的表现可能不同)。

我建议你阅读fork manual,这是非常明确的:

  

fork()通过复制调用进程来创建新进程。该   新的被称为孩子,是一个完全重复的呼叫   过程,称为父进程,但以下几点除外:

     
      
  • 子项具有自己唯一的进程ID,并且此PID与任何现有进程组(setpgid(2))的ID不匹配。

  •   
  • 子进程的父进程ID与父进程ID相同。

  •   
  • 孩子没有继承父母的记忆锁(mlock(2),mlockall(2))。

  •   
  • 进程资源利用率(getrusage(2))和CPU时间计数器(times(2))在子进程中重置为零。

  •   
  • 孩子的待处理信号集最初为空(sigpending(2))。

  •   
  • 孩子不会从其父级(semop(2))继承信号量调整。

  •   
  • 子进程不会从其父进程继承记录锁(fcntl(2))。

  •   
  • 孩子不会从其父级(setitimer(2),alarm(2),timer_create(2))继承计时器。

  •   
  • 子进程不从其父进程(aio_read(3),aio_write(3)继承未完成的异步I / O操作,也不继承   来自其父级的任何异步I / O上下文(参见io_setup(2))。

  •   
     

前面列表中的进程属性都是在中指定的   POSIX.1-2001。父母和孩子在这方面也有所不同   遵循特定于Linux的流程属性:

     
      
  • 子项不会从其父项继承目录更改通知(dnotify)(请参阅fcntl(2)中的F_NOTIFY说明)。

  •   
  • prctl(2)PR_SET_PDEATHSIG设置已重置,以便子节点在其父节点终止时不会收到信号。

  •   
  • 标有madvise(2)MADV_DONTFORK标记的内存映射不会在fork()中继承。

  •   
  • 孩子的终止信号始终为SIGCHLD(请参阅clone(2))。

  •   
     

请注意以下几点:

     
      
  • 使用单个线程创建子进程 - 调用fork()的线程。父级的整个虚拟地址空间是   复制在孩子身上,包括互斥状态,状况   变量和其他pthreads对象;使用pthread_atfork(3)   可能有助于解决这可能导致的问题。

  •   
  • 子进程继承了父进程打开文件描述符的副本。子中的每个文件描述符都指向相同的open   文件描述(参见open(2))作为相应的文件描述符   在父母。这意味着两个描述符共享打开文件   状态标志,当前文件偏移和信号驱动的I / O属性   (请参阅F_SETOWN(2)中F_SETSIGfcntl的说明。

  •   
  • 子项继承了父组的开放消息队列描述符的副本(请参阅mq_overview(7))。孩子中的每个描述符   指的是与对应的相同的开放消息队列描述   父级中的描述符。这意味着两个描述符共享   相同的旗帜(mq_flags)。

  •   
  • 子进程继承了父进程打开目录流的副本(参见opendir(3))。 POSIX.1-2001表示相应的   父级和子级中的目录流可以共享该目录   流定位;在Linux / glibc上他们没有。

  •   

如果您对Linux感兴趣,还应该检查clone系统调用,以便更准确地指定您想要的内容。

答案 1 :(得分:5)

系统上的fork(2)手册页(man fork)应该为您提供更好的细节,但通常孩子只会继承父文件描述符列表,包括打开文件,套接字和进程句柄。

从我系统的手册页(Mac OS X 10.6.6):

  

子进程有自己父级描述符的副本。       这些描述符引用相同的底层对象,因此       例如,文件对象中的文件指针是共享的       在孩子和父母之间,使一个lseek(2)       子进程中的描述符可能会影响后续的读取或       由父母写。此描述符复制也被使用       shell为新创建标准输入和输出       处理过程以及设置管道。

答案 2 :(得分:2)

答案 3 :(得分:1)

C中没有面向对象的继承。

C中的fork基本上是在它运行时被停止的进程,并且它的整个副本(有效地)在不同的内存空间中进行,然后两个进程被告知继续。他们将继续从父母暂停的地方继续。您可以判断自己所处的流程的唯一方法是检查fork()来电的返回值。

在这种情况下,孩子并没有真正继承父母过程中的所有内容,更像是获得父母所拥有的所有内容的完整副本。

答案 4 :(得分:0)

与父母不同的孩子唯一的事情是

PPID即父进程ID

PID流程ID

当涉及到相似性时,子进程继承其父级的FILE DESCRIPTOR表,因此您会看到总是占用三个子级的FILE DESCRIPTORS,它们对应于 STDIN,STDOUT和STDERR