2

我知道之后,fork()级打开的所有文件(及其偏移量)都由 子共享。即父子共享所有文件的文件表项。

如果孩子打开某个文件会发生什么。是专门针对孩子的吗?还是由父母共享?

我还编写了小型测试程序。这是测试这个的正确方法吗?

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>

#define FLAG (O_RDWR | O_CREAT | O_TRUNC)

int main(int argc, char *argv[])
{
    pid_t pid;

    if ((pid = fork()) < 0) {
        perror("fork error");
        exit(1);
    } else if (pid == 0) {
        int fc;
        if ((fc = open("abc", FLAG)) == -1) {
            perror("cannot open abc");
            exit(-1);
        }
        exit(fc);
        //returning the file descriptor open through exit()
    } else {
        int fp;
        wait(&fp);
        if (fp == -1)
            exit(1);
        if (fcntl(fp, F_GETFD) == -1)
            perror("doesn't work");     //Ouputs: doesn't work: Bad file descriptor
        //returns file descriptor flags
        //should not return error, if fd is valid
    }
    return 0;
}

谢谢。

4

4 回答 4

5

子进程在fork().

如果您在子级中打开文件,则不会与父级共享。

此外,如果您在父进程中打开文件后fork()不会与子进程共享。

于 2013-04-19T10:59:56.167 回答
0

当您的子进程退出时,所有剩余的打开文件都将关闭。因此,当父母尝试使用它时,它不再有效。

于 2013-04-19T11:01:50.740 回答
0

人叉

子继承父的一组打开文件描述符的副本。子文件中的每个文件描述符与父文件中的相应文件描述符引用相同的打开文件描述(请参阅 open(2))。这意味着两个描述符共享打开文件状态标志、当前文件偏移量和信号驱动的 I/O 属性(参见 fcntl(2) 中对 F_SETOWN 和 F_SETSIG 的描述)。

如果您关闭子文件中的文件,它也将在父文件中关闭。

于 2013-04-19T11:03:28.183 回答
0

我有这段代码,我看到文件描述符与父 pid 共享

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>


pid_t p;

int main(){
    if((p = fork()) != -1){
            open("file",O_APPEND);
            sleep(120);
    }
}

gcc -o fork fork.c

root      4576  2675  0 06:39 ttyS0    00:00:00 ./fork
root      4577  4576  0 06:39 ttyS0    00:00:00 ./fork

lsof -p 4576
COMMAND  PID USER   FD   TYPE DEVICE SIZE/OFF  NODE NAME
fork    4576 root  cwd    DIR    8,1     4096 69266 /root
fork    4576 root  rtd    DIR    8,1     4096     2 /
fork    4576 root  txt    REG    8,1     9882 70117 /root/fork
fork    4576 root  mem    REG    8,1  1682436 23185 /lib/libc-2.11.3.so
fork    4576 root  mem    REG    8,1   143987 23174 /lib/ld-2.11.3.so
fork    4576 root    0u   CHR   4,64      0t0  3340 /dev/ttyS0
fork    4576 root    1u   CHR   4,64      0t0  3340 /dev/ttyS0
fork    4576 root    2u   CHR   4,64      0t0  3340 /dev/ttyS0
fork    4576 root    3r   REG    8,1        0 75269 /root/file

lsof -p 4577
COMMAND  PID USER   FD   TYPE DEVICE SIZE/OFF  NODE NAME
fork    4577 root  cwd    DIR    8,1     4096 69266 /root
fork    4577 root  rtd    DIR    8,1     4096     2 /
fork    4577 root  txt    REG    8,1     9882 70117 /root/fork
fork    4577 root  mem    REG    8,1  1682436 23185 /lib/libc-2.11.3.so
fork    4577 root  mem    REG    8,1   143987 23174 /lib/ld-2.11.3.so
fork    4577 root    0u   CHR   4,64      0t0  3340 /dev/ttyS0
fork    4577 root    1u   CHR   4,64      0t0  3340 /dev/ttyS0
fork    4577 root    2u   CHR   4,64      0t0  3340 /dev/ttyS0
fork    4577 root    3r   REG    8,1        0 75269 /root/file

使用此 python 代码的相同结果:

#!/usr/bin/env python

import os
import time

print os.getpid()

if os.fork() is not None:
  print os.getpid()
  fd = open("/etc/passwd","r")
  time.sleep(120)

现在您可以检查父进程和子进程:

python pyfork.py
25131
25131
25132

lsof -p 25131
......
......
......
python  25131 root    3r   REG    8,8      2080  143680 /etc/passwd

lsof -p 25131
......
......
......
python  25132 root    3r   REG    8,8      2080  143680 /etc/passwd
于 2013-10-21T14:23:05.963 回答