2

在 Unix 上,我知道在调用 fork() 之后,我需要在调用 exec() 之前重置我的信号掩码并关闭我不希望孩子拥有的文件描述符。

但是,我还需要做什么?

是否有一个全面的文档列出了在分叉子进程时您可能想要清理的所有内容,以便为其提供一个很好的标准执行环境?

我目前在 Linux 上,但我想要一份包含其他 Unix 的详细信息的文档,可能还有对它们进行自动配置测试的方法。

4

1 回答 1

0

fork(3)提供了一个全面的列表。在这里引用有点长,但根据 SO 政策,无论如何我都会这样做:

fork() 函数将创建一个新进程。新进程(子进程)应是调用进程(父进程)的精确副本,以下详述除外:

  • 子进程应具有唯一的进程 ID。
  • 子进程 ID 也不应与任何活动进程组 ID 匹配。
  • 子进程应该有一个不同的父进程ID,它应该是调用进程的进程ID。
  • 子进程应拥有自己的父文件描述符副本。每个子文件描述符都应与父文件描述符对应的打开文件描述相同。
  • 子进程应该有它自己的父打开目录流的副本。子进程中的每个打开的目录流可以与父进程对应的目录流共享目录流定位。
  • 子进程应该有它自己的父消息目录描述符的副本。
  • 子进程的 tms_utime、tms_stime、tms_cutime 和 tms_cstime 值应设置为 0。
  • 距闹钟信号发出的剩余时间应归零,如有报警,应取消;见警报()。
  • 应清除所有 semadj 值。
  • 父进程设置的文件锁不能被子进程继承。
  • 子进程的未决信号集应初始化为空集。
  • 间隔计时器应在子进程中重置。
  • 在父进程中打开的任何信号量也应在子进程中打开。
  • 子进程不应继承父进程通过调用 mlockall() 或 mlock() 建立的任何地址空间内存锁。
  • 在父进程中创建的内存映射应保留在子进程中。从父级继承的 MAP_PRIVATE 映射也应是子级中的 MAP_PRIVATE 映射,并且父级在调用 fork() 之前对这些映射中的数据所做的任何修改都应对子级可见。在 fork() 返回后由父级对 MAP_PRIVATE 映射中的数据进行的任何修改都应仅对父级可见。子进程对 MAP_PRIVATE 映射中数据的修改应仅对子进程可见。
  • 对于 SCHED_FIFO 和 SCHED_RR 调度策略,子进程应在 fork() 函数期间继承父进程的策略和优先级设置。对于其他调度策略,fork() 上的策略和优先级设置是实现定义的。
  • 父进程创建的每进程计时器不应被子进程继承。
  • 子进程应该有它自己的父消息队列描述符的副本。子节点的每个消息描述符都应与父节点的相应消息描述符引用相同的打开消息队列描述。
  • 子进程不得继承任何异步输入或异步输出操作。
  • 应使用单个线程创建进程。如果多线程进程调用 fork(),则新进程应包含调用线程及其整个地址空间的副本,可能包括互斥锁和其他资源的状态。因此,为避免错误,子进程只能执行异步信号安全操作,直到调用其中一个 exec 函数。Fork 处理程序可以通过 pthread_atfork() 函数建立,以便在 fork() 调用中维护应用程序不变量。当应用程序从信号处理程序调用 fork() 并且 pthread_atfork() 注册的任何 fork 处理程序调用非异步信号安全的函数时,行为未定义。
  • 如果同时支持 Trace 选项和 Trace Inherit 选项:如果调用进程在其继承策略设置为 POSIX_TRACE_INHERITED 的跟踪流中被跟踪,则子进程应被跟踪到该跟踪流中,并且子进程应继承父跟踪事件名称到跟踪事件类型标识符的映射。如果正在跟踪调用进程的跟踪流将其继承策略设置为 POSIX_TRACE_CLOSE_FOR_CHILD,则不应将子进程跟踪到该跟踪流中。通过调用 posix_trace_attr_setinherited() 函数来设置继承策略。
  • 如果支持 Trace 选项,但不支持 Trace Inherit 选项:子进程不应被跟踪到其父进程的任何跟踪流中。
  • 如果支持 Trace 选项,则跟踪控制器进程的子进程不应控制由其父进程控制的跟踪流。
  • 子进程的 CPU 时间时钟的初始值应设置为零。
  • 子进程单线程的CPU时间时钟初始值应设置为零。IEEE Std 1003.1-2001 定义的所有其他进程特性在父进程和子进程中应相同。IEEE Std 1003.1-2001 未定义的过程特性的继承未由 IEEE Std 1003.1-2001 指定。
于 2014-02-08T18:15:19.727 回答