vfork中的return和exit详解

来源:互联网 发布:nba2k17人物数据 编辑:程序博客网 时间:2024/06/06 13:23
一. 首先我们需要了解 vfork创建一个子进程, 并且父子进程是**共享**一片内存区域的。(fork创建的子进程是拷贝父进程的代码段,堆栈段,数据段,PCB)可以理解为vfork的子进程是在父进程的空间中存活。二. return是函数的返回,返回后释放堆栈资源    exit是进程的结束,系统级别的,直接退出整个进程进入正题return和exit在代码中的使用以及对程序的影响情况。
  1. 当不使用return和exit时候
    这里写图片描述

    这里写图片描述
    这里先啰嗦两句。
    错误实质就是我们也常会遇到的段错误,这里我用的中文版本,,竟然没打印段错误几个字,,也是醉了。不过通常都是段错误(数组访问越界什么的 都会发生这个错误)
    C99 无返回值,默认返回一个int 类型的整型,所以20行代码可有可无,情况是一样的。
    由运行结果我们可以看出 vforkv()以下的代码运行的顺序是 :
    **子进程代码(id)->主函数代码->return(默认)->父进程代码->主函数代码->
    return(默认).**
    现在有一个房间(父进程的房间),vfork之后子进程进入其中,
    第一次return(默认),子进程要被踢出房间了,子进程生气的把堆栈毁掉。
    第二次return(默认),父进程被踢出自己房间, 父进程也很生气,想要毁掉堆栈 发现被人毁了, 恼火万分之下之后把自己的房间烧了, 操作系统大哥就给跪了,程序gg。
    实质呢? 其中有两次return(默认)。 第一次return(默认)后释放堆栈资源, 所以父进程打印值的时候是乱码。出错则是因为第二次return(默认),释放了已经被释放过的堆栈,相当于free一个非空指针两次(或者执行多次析构),这是绝对错误的。

  2. 主函数调用exit函数
    这里写图片描述

这里写图片描述
**子进程代码(id)->主函数代码->exit->父进程代码->主函数代码->
exit**
现在有一个房间(父进程的房间),vfork之后子进程进入其中,
第一次exit操作系统大哥把子进程赶出去, 第二次exit把父进程赶出去,房间没人然后被拆迁队拆了:( 至于为什么第二次num的值是正确的,是子进程退出了房间,父进程仍然在房间中待着,其他进程无权跨进程访问,所以数据仍然存在。父进程可以正确的访问自己房间的堆栈段的数据。

  1. 子进程return 父进程exit

这里写图片描述

这里写图片描述

子进程return 摧毁堆栈,干了坏事赶紧跑出房间。 父进程一看数据被毁了,随便给我们读了个垃圾数字算是交代了任务, 操作系统大哥把他也从房间轰出去, 两人早早的都出了房间, 故21行的代码谁都看不到。
22,23行代码可有可无,反正谁都不会走到这里就被赶出去了。

  1. 子进程exit 父进程return

这里写图片描述

运行结果

前面都明白了 这里也很简单,子进程刚打印一句话就被操作系统大哥轰出去,父进程也打印这句话,摧毁堆栈,赶紧跑出房间。22,23行代码同上不会执行。

总结: return关键字, 不论有无人,都摧毁堆栈,然后退出房间。
exit函数,直接退出房间, 看放间里有人吗, 没人摧毁。
有人的话 等人走了再摧毁。
所以vfork代码中,无论哪里,只要调用了exit函数就不会出现段错误。

结论: 父子进程都return掉堆栈的话,产生段错误。所以vfork必须要调用一次exit函数(位置随意,并非必须在子进程中),或者调用exec族函数,拉起一个进程,这个读者可以下去了解。

原创粉丝点击