日期:2014-05-16  浏览次数:20681 次

open后fork问题
下面的代码中,close(iFileOpen);这句会被调用两次,正确吗?

#include <ctype.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>

int main(void)
{
  int iFileOpen, iReturn;

// 打开重定向文件,不存在则创建...
iFileOpen = open("./RedirFile.log", O_RDWR | O_CREAT);
  if (iFileOpen < 0) {
  perror("open fail: file=./RedirFile.log");
  return -1;
  }

printf("iReturn=%d, will fork\n", iReturn);
iReturn = fork();
if (0 == iReturn) // 在子进程中.
{
printf("I am running in child!\n");
}
else
{
printf("I am running in parent!\n");
}

printf("iFileOpen=%d, will close\n", iFileOpen);
close(iFileOpen); // open应只有一次,这里调用两次,正确吗????

printf("iReturn=%d, will return\n", iReturn);
return 0;
}


------解决方案--------------------
父亲进程关闭父进程的,子进程关闭子进程的,标准写法

你那样写也行
父亲进程,子进程都关闭了文件才真正关闭
------解决方案--------------------
fork后子进程继承了父进程的这个fd , ,
从进程的角度说,子进程关闭子进程的fd,父进程关闭父进程的fd,互不影响!
所以要么主动close,要么等进程结束时,操作系统自动关闭。。 看你程序中fork出的父子进程的逻辑了
这个问题看下《unix环境高级编程》8.3节 fork函数

------解决方案--------------------
通过fork()创建子进程时,子进程继承父进程环境和上下文的大部分内容的拷贝,其中就包括文件描述符表。
对于父进程在fork()之前打开的文件来说,子进程都会继承,与父进程共享相同的文件偏移量。

系统文件表(SFT)位于系统空间中,不会被fork()复制
但是系统文件表中的条目会保存指向它的文件描述符表的计数,fork()时需要对这个计数进行维护,以体现子进程对应的新的文件描述符表也指向它。
程序关闭文件时,也是将系统文件表条目内部的计数减一,当计数值减为0时,才将其删除。
------解决方案--------------------
close动作是在call fork()之后进行的,那么父进程和子进程都会call一次close,所以就是close动作就会执行两次。
------解决方案--------------------
父进程Open一次,fd被fork继承到子进程,父子进程的同一个fd都引用了该文件表项,直到父子进程都关闭该fd该文件表项才实际释放。

这里fork后父子进程都跑close是正确的,当然即便你不调close,进程退出也会关闭fd。