免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
123下一页
最近访问板块 发新帖
查看: 5233 | 回复: 20
打印 上一主题 下一主题

[C] 请教exit函数 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2008-01-28 12:44 |只看该作者 |倒序浏览
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <sys/types.h>

  4. int glob = 6;

  5. int main(void)
  6. {
  7.         int var;
  8.         pid_t pid;

  9.         var = 88;
  10.         printf("before fork\n");

  11.         if (0 > (pid = vfork()))
  12.         {
  13.                 printf("vfork error\n");
  14.                 exit(0);
  15.         }
  16.         else if (0 == pid)
  17.         {
  18.                 var++;
  19.                 glob--;
  20.                 exit(0);
  21.         }
  22.         printf("pid = %d, glob = %d, var = %d\n", getpid(), glob, var);

  23.         exit(0);
  24. }
复制代码


子进程中调用exit的话会把父进程打开的文件全部关闭了吧
但是实际运行的时候为什么还会有输出呢? 高人解释一下, 谢谢~~

论坛徽章:
0
2 [报告]
发表于 2008-01-28 12:46 |只看该作者
子进程关闭的是子进程的,不会关闭父进程,实际上,只是把引用减一。

论坛徽章:
0
3 [报告]
发表于 2008-01-28 13:23 |只看该作者
原帖由 cugb_cat 于 2008-1-28 12:46 发表
子进程关闭的是子进程的,不会关闭父进程,实际上,只是把引用减一。


vfork() 后子进程还是在父进程的空间中运行的吧
所以关闭的应该是父进程的

论坛徽章:
0
4 [报告]
发表于 2008-01-28 13:32 |只看该作者
原帖由 andre.ease 于 2008-1-28 13:23 发表


vfork() 后子进程还是在父进程的空间中运行的吧
所以关闭的应该是父进程的


你理解一下cugb_cat说的那句话: 实际上,只是把引用减一.
虽然是在它的父进程中运行的, 但是子进程也有它自己的文件表项. 地址空间与文件表项不一样的.
你看APUE中fork那一节关于fork之后的文件表就明白了.

论坛徽章:
0
5 [报告]
发表于 2008-01-28 13:35 |只看该作者
原帖由 andre.ease 于 2008-1-28 13:23 发表


vfork() 后子进程还是在父进程的空间中运行的吧
所以关闭的应该是父进程的

不好意思,没看清是vfork,刚才man了一下,楼主参考一下这段话:
       vfork() differs from fork(2) in that the parent is  suspended  until  the  child  makes  a  call  to
       execve(2)  or  _exit(2).   The  child  shares all memory with its parent, including the stack, until
       execve(2) is issued by the child.  The child must not return  from  the  current  function  or  call
       exit(3), but may call _exit(2).
父进程调用vfork创建子进程后,父进程就挂起了,直到自己成调用execve或者_exit,但调用exit子进程是退出不了的。
我想,那打印的应该是子进程打印的,你可以把进程号打印出来看看。

[ 本帖最后由 cugb_cat 于 2008-1-28 13:36 编辑 ]

论坛徽章:
0
6 [报告]
发表于 2008-01-28 13:37 |只看该作者
原帖由 scutan 于 2008-1-28 13:32 发表


你理解一下cugb_cat说的那句话: 实际上,只是把引用减一.
虽然是在它的父进程中运行的, 但是子进程也有它自己的文件表项. 地址空间与文件表项不一样的.
你看APUE中fork那一节关于fork之后的文件表就明白了.

刚才没仔细看,vfork和fork有点点不同。:wink:

论坛徽章:
0
7 [报告]
发表于 2008-01-28 13:44 |只看该作者
原帖由 cugb_cat 于 2008-1-28 13:35 发表

不好意思,没看清是vfork,刚才man了一下,楼主参考一下这段话:
       vfork() differs from fork(2) in that the parent is  suspended  until  the  child  makes  a  call  to
       execve(2)  or   ...


那个最后打印的也是父进程打印的, 即使在子进程中调用
close(0);close(1);close(2);
最后父进程仍然能够打印出来. 因为在子进程中关闭的是子进程的file descriptor中的, 此时父,子进程各有一个task_struct结构了. 关闭子进程的对父进程没有关系.
而地址空间是task_struct->mm_struct中的. 此时由父子进程共享.

论坛徽章:
0
8 [报告]
发表于 2008-01-28 13:54 |只看该作者
原帖由 scutan 于 2008-1-28 13:44 发表


那个最后打印的也是父进程打印的, 即使在子进程中调用
close(0);close(1);close(2);
最后父进程仍然能够打印出来. 因为在子进程中关闭的是子进程的file descriptor中的, 此时父,子进程各有一个task_struc ...

刚才实验了一下,确实是父进程打印的,man vfork中说Linux中调用vfork函数,父进程会等到自进程调用exec或_exit才会继续运行,而且vfork出来的子进程跟父进程是暂时共享地址空间的,不过没说打开的描述符是否也是共享的。

论坛徽章:
0
9 [报告]
发表于 2008-01-28 14:04 |只看该作者
刚看了下ULK
The vfork( ) system call, introduced in the previous section, is implemented by Linux as a clone( ) system call whose flags parameter specifies both a SIGCHLD signal and the flags CLONE_VM and CLONE_VFORK, and whose child_stack parameter is equal to the current parent stack pointer.

Linux中的vfork函数产生的子进程和父进程是不共享打开的文件描述符的,因为vfork在调用clone产生进程时没有使用CLONE_FILES标志。
所以在对待打开的描述符的情况下和fork是一样的。

论坛徽章:
0
10 [报告]
发表于 2008-01-28 14:06 |只看该作者
原帖由 cugb_cat 于 2008-1-28 13:54 发表

刚才实验了一下,确实是父进程打印的,man vfork中说Linux中调用vfork函数,父进程会等到自进程调用exec或_exit才会继续运行,而且vfork出来的子进程跟父进程是暂时共享地址空间的,不过没说打开的描述符是否 ...


在linux中从源码来看是不共享的.

sys_vfork->do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, ...)->copy_process->copy_files
在copy_files中:
if (clone_flags & CLONE_FILES) {
               atomic_inc(&oldf->count);
               goto out;
}
tsk->files = NULL;
newf = dup_fd(oldf, &error);
if (!newf)
        goto out;

tsk->files = newf;
由于flags中没有CLONE_FILES, 故不会共享.
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP