2016-09-20 112 views
2

当我使用fork()创建子进程时,该子进程是父进程的副本。指针是指向每个进程中的同一事物,还是指针在子进程中有一个新的值。数组或文件指针怎么样?fork()是否创建别名?

+0

在孩子的指针持有相同的地址在父指针。它指向的地址在孩子和父母中都保持相同的数据。如果其中一个进程写入该值,则在该进程中会有所不同,但不会在其他进程中进行写入。如果一个进程从FILE *中读取,则其FILE *的内部副本被更新(例如,它在文件中的位置),但不在另一个进程中。但是,在两个进程中都可以看到修改底层文件描述符的任何内容。 –

+0

所以指针指向相同的值,但同一个值的两个不同的副本?这是我很好奇的,当我读到你的评论时,你说的是什么? –

+0

指针*具有相同的值,它们指向的*在每个进程中返回的即时fork()处都相同。之后会发生什么取决于每个过程:他们的地址空间是不同的。 – EJP

回答

3

指针指向每个进程中的同一事物。

是的,所有的记忆被复制,包括指针。

数组或文件指针怎么样?

是的。在文件描述的情况下,它是有用的注意,任何文件描述符的家长开放,将引用相同的文件在子进程。


大多数(所有?)Unix系统使用某种形式的副本上写的优化,这意味着该过程实际上将共享物理内存,直到他们写存储器。这往往会使fork()成为一个相当便宜的操作。

有拐角的情况下,由巴斯克斯 - 艾布拉姆斯指出。也许最重要的是只有一个线程分叉,即调用fork()系统调用的线程。

0

fork(2) man page(重点煤矿):

新工艺,被称为孩子,是确切的重复调用进程的,被称为父,除了以下点

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

* 孩子的父进程ID与父进程ID相同。

* 孩子不继承父母的记忆锁(mlock(2),mlockall(2))。

* 子进程资源利用率(getrusage(2))和CPU时间计数器(次数(2))被重置为零。

* 孩子的待决信号集最初是空的(sigpending(2))。

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

* 子项不从其父项(fcntl(2))继承记录锁。

* 孩子不从父母(setitimer(2),alarm(2),timer_create(2))继承定时器。

* 的孩子不继承其父未完成的异步I/O操作(的aio_read(3),aio_write(3)),也没有继承任何异步I/O上下文从它的父(见io_setup(2 ))。

上述列表中的进程属性全部在POSIX.1-2001中指定。父项和子项在以下特定于Linux的进程属性方面也有所不同:

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

* prctl(2)PR_SET_PDEATHSIG设置被重置,以便孩子在其父母终止时不会收到信号。

* 默认计时器松弛值设置为父亲的当前计时器松弛值。请参阅prctl(2)中的PR_SET_TIMERSLACK说明。

* 用madvise(2)MADV_DONTFORK标志标记的内存映射不会通过fork()继承。

* 孩子的终止信号总是SIGCHLD(参见克隆(2))。

* ioperm(2)设置的端口访问权限位不会被子级继承;孩子必须使用ioperm打开它需要的任何位(2)。

请注意以下几点进一步指出:与单个线程创建

* 子过程 - 一个调用fork()的。父项的整个虚拟地址空间在子项中复制,包括互斥锁,条件变量和其他pthreads对象的状态;使用pthread_atfork(3)可能有助于处理这可能导致的问题。

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

* 子继承了父节点的打开消息队列描述符集的副本(请参阅mq_overview(7))。子代中的每个描述符都指向与父代中相应描述符相同的开放消息队列描述。这意味着这两个描述符共享相同的标志(mq_flags)。

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

+2

我直接去了手册页,但它只是有点难以破译。 –

+0

“孩子继承了父节点的打开文件描述符集合的副本,子节点中的每个文件描述符都指向父节点中相应的文件描述符(参见open(2)),这意味着两个描述符共享打开的文件状态标志,当前文件偏移量和信号驱动的I/O属性(请参阅fcntl(2)中的F_SETOWN和F_SETSIG的说明)。“ –