文件是由fork之后的child创建的,也是与父级共享的吗?

文件是由fork之后的child创建的,也是与父级共享的吗?,c,linux,unix,fork,C,Linux,Unix,Fork,我知道在fork()之后,父级打开的所有文件(及其偏移量)都是共享的 通过子对象。也就是说,父级和子级共享所有文件的文件表条目 如果孩子打开某个文件会发生什么。它是针对儿童的吗?还是由家长共享 我还编写了小型测试程序。这是测试这个的正确方法吗 #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <stdlib.h> #include <stdio.h

我知道在
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;
}
#包括
#包括
#包括
#包括
#包括
#包括
#定义标志(O_RDWR | O_CREAT | O_TRUNC)
int main(int argc,char*argv[])
{
pid_t pid;
如果((pid=fork())<0){
perror(“分叉错误”);
出口(1);
}否则如果(pid==0){
国际金融中心;
如果((fc=打开(“abc”,标志))=-1){
perror(“无法打开abc”);
出口(-1);
}
出口(fc);
//返回通过exit()打开的文件描述符
}否则{
int-fp;
等待(&fp);
如果(fp==-1)
出口(1);
如果(fcntl(fp,F_GETFD)=-1)
perror(“不工作”);//输出:不工作:文件描述符错误
//返回文件描述符标志
//如果fd有效,则不应返回错误
}
返回0;
}

谢谢

在执行
fork()
时,子对象将获得父对象的文件描述符的副本

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


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

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

:

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


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

我有此代码,我看到文件描述符与父级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 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

简而言之:不。孩子在分叉的那一刻得到了父母句柄的快照,之后发生的一切都不会被反映出来。@MM。我在child中打开文件是在
fork
之后,而不是在引用的问题之前。这不是所建议的问题的重复。询问在分叉之前打开的文件描述符;这会询问分叉后创建的文件描述符。情况和答案完全不同。当子项退出时,所有文件都将关闭。既然父
stdout
也是共享的,为什么不关闭?您使用什么函数关闭所有文件描述符?我的意思是正常退出是否关闭所有文件?不,它不关闭。根据您的操作系统及其配置,文件将自动关闭或不关闭。linux上的文件描述符在进程大部分时间结束后关闭,但如果文件描述符仍由另一个进程使用,它不会关闭。但我想知道,在子进程的活动时间内,父进程是否可以看到子进程打开的文件描述符。您的lsof输出显示,每个进程恰好有一个文件描述符打开到同一个文件(节点)。它没有告诉你他们正在共享一个打开的文件描述。好吧,是和否。你发布的lsof输出有一个名为NODE的列,这就是我想提请你注意的。该字段中值的含义是文件的inode。如果在子进程中打开/root/文件,为什么进程4576会看到文件描述符3?代码中有一个错误:fork()在子进程中返回0,在父进程中返回子进程的pid。对于父进程和子进程,您的条件都为true,因此它们都将打开相同的文件。@xyz我认为我的C代码中没有错误,我用python编写,问题是相同的,fork之后打开的文件描述符与父进程共享,我想这是因为父进程和子进程使用相同的文件描述符表。
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