进程【6】-理解进程的终止:exit,_exit,return


前言

提示:这里要解决以下问题

  1. 进程是如何退出的,具体过程是什么?
  2. exit,_exit,return,有什么区别?
  3. 块缓冲和行缓冲的区别?

一、进程是如何退出的,具体过程是什么?

  • 看看return和exit的差别

在linux上分别跑一下这个代码

int main()
{
	return 0;
	//exit(0);
}

return 0
在这里插入图片描述

exit 0
在这里插入图片描述
在这里插入图片描述
结论:
return() 会弹出栈,将释放局部变量。而exit()会进入内核,告知内核进程已死,并回收资源。
规定vfork()绝不可以调用return()

二. exit,_exit,return,有什么区别?

  • return() 代表调用栈的返回,exit()代表一个过程的结束。
  • 从main函数退出,会隐式的调用exit()函数,并将return的返回值传递给exit().
  • 从exit()退出,会先调用退出程序,刷新stdio流缓冲区,使用由status提供的值执行_exit()系统调用
  • return 是关键字,exit()是库函数。

三. 块缓冲和行缓冲的区别

用例子来引出问题:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>

int main(int argc, char **argv)
{
    printf("hello world\n");
    write(STDOUT_FILENO,"Ciao\n",5);
    if (fork() == -1)
        exit(-1);
    exit(EXIT_SUCCESS);
}

输出到终端时:

>>> a.out 
hello world
Ciao

输出到文件中时:

>>> a.out > test.md
[xxxx@ubuntu ~/practice]@practice
>>> cat test.md 
Ciao
hello world
hello world

printf()输出行出现了两次,且write()的输出先于printf()
要理解这个问题,那么要记住:stdio缓冲区是维护在进程的用户空间内存中的,fork()会复制缓冲区给子进程。第一次因为缺省缓冲区为行缓冲区,可以立即显示printf()输出的包含换行符的字符串。
但是输出到文件就成了块缓冲区,只有到了父进程和子进程调用exit()之后,刷新了两次stdio缓冲区,所以打印了两次printf();

  • 那么为什么write()会出现在printf之前呢,还只出现了一次?
    这是因为write(),会将数据传送至内核缓冲,fork()不会复制这一缓冲区。
  • 行缓冲区遇到换行符/时间够长/数据够多/程序结束,就会输出;而块缓冲区,只会因为数据量足够多的时候才会输出。
    以下代码不会出现上述问题
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>

int main(int argc, char **argv)
{
    printf("hello world\n");
    fflush(stdout);
    write(STDOUT_FILENO,"Ciao\n",5);
    if (fork() == -1)
        exit(-1);
    exit(EXIT_SUCCESS);
}

总结

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值