我知道在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;
}
感谢。
答案 0 :(得分:5)
孩子在fork()
时刻获得父母的文件描述符的副本。
如果您在孩子中打开一个文件,则不会与父母共享。
此外,如果您在fork()
之后在父进程中打开文件,则不会与该子进行共享。
答案 1 :(得分:0)
当您的子进程退出时,所有剩余的打开文件将被关闭。因此,当父母尝试使用它时,它就不再有效了。
答案 2 :(得分:0)
子进程继承父进程打开文件的副本 描述。 子中的每个文件描述符都指向相同的打开文件 description(参见open(2))作为相应的文件描述符 家长。这意味着两个描述符共享打开文件状态 标志,当前文件偏移和信号驱动的I / O属性(参见 fcntl(2)中的F_SETOWN和F_SETSIG的描述。
如果您关闭子项中的文件,它也将在父项中关闭。
答案 3 :(得分: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