所以我对子进程可以访问的内容有疑问。
如果父文件open()是一个文件,然后fork()是一个子文件,子进程是否可以访问打开的文件,还是需要打开文件本身?是否可以通过进程之间的共享内存访问已打开的文件? (C编程)
答案 0 :(得分:3)
简短回答是的。
您可以在此处详细了解: http://man7.org/linux/man-pages/man2/fork.2.html
正如在那里所说的那样,子进程与父进程完全相同,除了 以下几点:
* The child has its own unique process ID, and this PID does not
match the ID of any existing process group (setpgid(2)).
* The child's parent process ID is the same as the parent's process
ID.
* The child does not inherit its parent's memory locks (mlock(2),
mlockall(2)).
* Process resource utilizations (getrusage(2)) and CPU time counters
(times(2)) are reset to zero in the child.
* The child's set of pending signals is initially empty
(sigpending(2)).
* The child does not inherit semaphore adjustments from its parent
(semop(2)).
* The child does not inherit process-associated record locks from
its parent (fcntl(2)). (On the other hand, it does inherit
fcntl(2) open file description locks and flock(2) locks from its
parent.)
* The child does not inherit timers from its parent (setitimer(2),
alarm(2), timer_create(2)).
* The child does not inherit outstanding asynchronous I/O operations
from its parent (aio_read(3), aio_write(3)), nor does it inherit
any asynchronous I/O contexts from its parent (see io_setup(2)).
The process attributes in the preceding list are all specified in
POSIX.1. The parent and child also differ with respect to the
following Linux-specific process attributes:
* The child does not inherit directory change notifications
(dnotify) from its parent (see the description of F_NOTIFY in
fcntl(2)).
* The prctl(2) PR_SET_PDEATHSIG setting is reset so that the child
does not receive a signal when its parent terminates.
* The default timer slack value is set to the parent's current timer
slack value. See the description of PR_SET_TIMERSLACK in
prctl(2).
* Memory mappings that have been marked with the madvise(2)
MADV_DONTFORK flag are not inherited across a fork().
* The termination signal of the child is always SIGCHLD (see
clone(2)).
* The port access permission bits set by ioperm(2) are not inherited
by the child; the child must turn on any bits that it requires
using ioperm(2).
Note the following further points:
* The child process is created with a single thread—the one that
called fork(). The entire virtual address space of the parent is
replicated in the child, including the states of mutexes,
condition variables, and other pthreads objects; the use of
pthread_atfork(3) may be helpful for dealing with problems that
this can cause.
* After a fork(2) in a multithreaded program, the child can safely
call only async-signal-safe functions (see signal(7)) until such
time as it calls execve(2).
* The child inherits copies of the parent's set of open file
descriptors. Each file descriptor in the child refers to the same
open file description (see open(2)) as the corresponding file
descriptor in the parent. This means that the two file
descriptors share open file status flags, file offset, and signal-
driven I/O attributes (see the description of F_SETOWN and
F_SETSIG in fcntl(2)).
* The child inherits copies of the parent's set of open message
queue descriptors (see mq_overview(7)). Each file descriptor in
the child refers to the same open message queue description as the
corresponding file descriptor in the parent. This means that the
two file descriptors share the same flags (mq_flags).
* The child inherits copies of the parent's set of open directory
streams (see opendir(3)). POSIX.1 says that the corresponding
directory streams in the parent and child may share the directory
stream positioning; on Linux/glibc they do not.
答案 1 :(得分:1)
是的,使用相同的文件描述符。不需要共享内存。
使用stdio FILE*
会有点工作,但我不建议您为计划写入的文件这样做,因为在两个单独的进程中缓冲会导致意外和混乱的结果。
为防止共享文件描述符 - 如果您愿意 - 当close()
调用返回0时,您当然可以在文件描述符上调用fork()
。