如果父母打开文件,然后分叉一个孩子,孩子是否可以访问打开的文件? (C编程)

时间:2016-03-15 21:53:51

标签: c fork parent-child parent child-process

所以我对子进程可以访问的内容有疑问。

如果父文件open()是一个文件,然后fork()是一个子文件,子进程是否可以访问打开的文件,还是需要打开文件本身?是否可以通过进程之间的共享内存访问已打开的文件? (C编程)

2 个答案:

答案 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()