文件是由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