fork vfork exit _exit (转)

原文地址:http://hi.baidu.com/ikaruga11/blog/item/fb6d75725a8d8d148701b080.html
APUE上的一个例子:

example1 (forkt.c ):

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

int glob = 5;

int main()
{
        int var=10;
        pid_t pid;

        printf("befork vfork\n");
        if((pid = fork()) < 0){
                printf("error\n");
                exit(1);
        }else if(pid == 0){
                glob++;
                var++;
                _exit(0);
        }
        printf("pid = %d, glob = %d, var = %d",getpid(), glob,var);
        exit(0);
}

执行
./forkt.c
./forkt.c > temp.out
将分别输出什么呢?

为了找出为什么会输出如上内容,以及fork vfork exit _exit的区别,于是改造上面的代码
example2:(省略了其他同上相同的代码)

        printf("befork vfork\n");
        if((pid = fork()) < 0){
                printf("error\n");
                exit(1);
        }else if(pid == 0){
                glob++;
                var++;
                exit(0);
        }
        printf("pid = %d, glob = %d, var = %d",getpid(), glob,var);
        _exit(0);
执行
./forkt.c
./forkt.c > temp.out
将分别输出什么呢?


example3:(省略了其他同上相同的代码)

        printf("befork vfork\n");
        if((pid = vfork()) < 0){
                printf("error\n");
                exit(1);
        }else if(pid == 0){
                glob++;
                var++;
                _exit(0);
        }
        printf("pid = %d, glob = %d, var = %d",getpid(), glob,var);
        exit(0);

执行
./forkt.c
./forkt.c > temp.out
将分别输出什么呢?



example4:(省略了其他同上相同的代码)

        printf("befork vfork\n");
        if((pid = vfork()) < 0){
                printf("error\n");
                exit(1);
        }else if(pid == 0){
                glob++;
                var++;
                exit(0);
        }
        printf("pid = %d, glob = %d, var = %d",getpid(), glob,var);
        _exit(0);

./forkt.c
./forkt.c > temp.out
将分别输出什么呢?


先把几个概念缕一缕:
   fork: 子进程拥有父进程的数据段、堆和栈的副本,父进程和子进程共享正文段。但现在很多实现却并不是将父进程的数据段、堆栈段进行完全拷贝,而是采用写时复制(copy-on-write),内核将其标记为只读,(典型的页式虚存)只有父进程或子进程对这些区域进行修改时内核才真正将那一页进行拷贝,从物理上分离开。
   vfork:由于在vfork后经常是跟着一个exec执行一个新的程序不会在用到原来的地址空间,所以vfork的子进程在调用exec或exit之前是在父进程的空间里运行的,这样对于页式虚存效率很高。另外,vfork的子进程总是先与父进程执行,但是子进程不能依赖与父进程的执行否则产生死锁。

exit(0):根据实现的不同而不同,一般是刷新I/O缓冲区,关闭所有I/O标准流(APUE上如是说,但是我在linux下验证的结果应该是没有关闭),一般现在的I/O库函数在关闭I/O流方面不自找麻烦了。

_exit(0):不刷新I/O缓冲区


标准I/O库:
标准I/O库是带缓存的,如果标准输出是连接到终端设备,则它是行缓冲的,否则是全缓冲的。行缓冲在接收到一个换行符才进行刷新,而全缓冲在缓冲区满或者程序在执行exit退出后在执行缓冲区刷新



好了 ,现在我们来看看上面的例子到底输出什么东东了

example1:

执行:./forkt.c
交互方式执行,则是行缓冲, befork vfork后跟一个换行符\n,则刷新缓冲区输出 befork vfork,然后fork一个子进程,父子进程分别运行在不同的存储空间,子进程执行_exit()退出,不刷新缓冲区,父进程执行最后一个printf,但由于没有遇到\n,所以并不立即输出,在执行exit(0)后刷新缓冲区,此时输出
pid =6724, glob = 5, var =10

执行:./forkt.c > temp.out
非交互方式,则是全缓冲,首先执行printf("befork vfork\n")此时并不输出,而是缓存在缓冲区,然后fork一个子进程,父子进程分别运行在不同的存储空间,拷贝一份父进程中缓冲区的befork vfork\n 到子进程,子进程执行_exit()退出,不刷新缓冲区,父进程执行最后一个printf,也缓存起来并不立即输出,在执行exit(0)后刷新缓冲区,此时输出全部输出
cat > temp.out 输出如下:
befork vfork
pid =6731, glob = 5, var =10


example2:

执行:./forkt.c
交互方式执行,则是行缓冲, befork vfork后跟一个换行符\n,则刷新缓冲区输出 befork vfork,然后fork一个子进程,父子进程分别运行在不同的存储空间,子进程执行exit()刷新缓冲区退出,父进程执行最后一个 printf,但由于没有遇到\n,所以并不立即输出,在执行_exit(0)后由于不刷新缓冲区而退出,所以最后一个printf内容并不输出。所以
执行:./forkt.c
befork vfork


执行:./forkt.c > temp.out
非交互方式,则是全缓冲,首先执行printf("befork vfork\n")此时并不输出,而是缓存在缓冲区,然后fork一个子进程,父子进程分别运行在不同的存储空间,同时拷贝一份父进程中缓冲区的befork vfork\n 到子进程,子进程执行exit()刷新缓冲区退出,此时输出befork vfork\n ,父进程执行最后一个printf,也缓存起来并不立即输出,在执行_exit(0)后由于不刷新缓冲区而退出,因此输出
cat > temp.out 输出如下:
befork vfork


example3:


执行:./forkt.c
交互方式执行,则是行缓冲, befork vfork后跟一个换行符\n,则刷新缓冲区输出 befork vfork,然后vfork一个子进程,父子进程运行在相同的存储空间,子进程执行_exit()不刷新缓冲区退出,父进程执行最后一个 printf,但由于没有遇到\n,所以并不立即输出,在执行exit(0)后刷新缓冲区而退出,所以最后一个printf内容输出。所以
执行:./forkt.c
befork vfork
pid =6802, glob = 6, var =11


执行:./forkt.c > temp.out
非交互方式,则是全缓冲,首先执行printf("befork vfork\n")此时并不输出,而是缓存在缓冲区,然后vfork一个子进程,父子进程运行在相同的存储空间,子进程执行_exit()不刷新缓冲区退出,父进程执行最后一个printf,也缓存起来并不立即输出,在执行exit(0)刷新缓冲区而退出,因此输出
cat > temp.out 输出如下:
befork vfork
pid =6808, glob = 6, var =11


example4:
执行:./forkt.c
befork vfork
pid =6802, glob = 6, var =11


执行:./forkt.c > temp.out

cat > temp.out 输出如下:
befork vfork
pid =6808, glob = 6, var =11

 

另外

简单的说,exit函数将终止调用进程。在退出程序之前,所有文件关闭,缓冲输出内容将刷新定义,并调用所有已刷新的“出口函数”(由atexit定义)。
_exit:该函数是由Posix定义的,不会运行exit handler和signal handler,在UNIX系统中不会flush标准I/O流。
简单的说,_exit终止调用进程,但不关闭文件,不清除输出缓存,也不调用出口函数。
共同:
不管进程是如何终止的,内核都会关闭进程打开的所有file descriptors,释放进程使用的memory!
note:
在由‘fork()’创建的子进程分支里,正常情况下使用‘exit()’是不正确的,这是 因为使用它会导致标准输入输出的缓冲区被清空两次,而且临时文件被出乎意料的删除(译者注:临时文件由tmpfile函数创建在系统临时目录下,文件名由系统随机生成)。
在C++程序中情况会更糟,因为静态目标(static objects)的析构函数(destructors)可以被错误地执行。
还有一些特殊情况,比如守护程序,它们的父进程需要调用‘_exit()’而不是子进程;适用于绝大多数情况的基本规则是,‘exit()’在每一次进入‘main’函数后只调用一次。

在由‘vfork()’创建的子进程分支里,‘exit()’的使用将更加危险,因为它将影响 父进程的状态

转载于:https://www.cnblogs.com/Myhsg/archive/2009/09/07/1562080.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/496254.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

VMware 安装 win7、win10、MAC 和网络模式VMnet0、VMnet1、VMnet8解释

VMware虚拟机安装ghost win7系统方法&#xff1a;http://www.xitongcheng.com/jiaocheng/xtazjc_article_15314.html VMWare14 安装Mac OS系统&#xff08;图解&#xff09;&#xff1a;http://blog.csdn.net/u011415782/article/details/78505422 虚拟机&#xff08;VMware …

Spring Data JPA 从入门到精通~关键字列表

注意除了 find 的前缀之外&#xff0c;我们查看 PartTree 的源码&#xff0c;还有如下几种前缀&#xff1a; private static final String QUERY_PATTERN "find|read|get|query|stream"; private static final String COUNT_PATTERN "count"; private s…

当科学遇上众包:9个值得关注的前沿科技算力众包平台

来源&#xff1a; 资本实验室 . 作者&#xff1a;李鑫找到癌症治疗的方法&#xff0c;预测气候的变化&#xff0c;追踪可能与地球相撞的小行星……甚至预测地震&#xff0c;我们每天都面临着各种世界性难题。如果你想参与解决这些难题&#xff0c;公民科学应用将让你发挥作用…

oracle数据库配置助手来初始化参数,使用服务器参数文件(SPFILE)管理初始化参数...

传统上&#xff0c;Oracle数据库的初始化参数存储在文本初始化参数文件中。为了更好的可管理性&#xff0c;您可以选择在二进制服务器参数文件中维护初始化参数&#xff0c;该文件在数据库启动和关闭期间保持不变。本节介绍服务器参数文件&#xff0c;并介绍如何使用任何一种存…

为脚本语言平反-JavaScript篇(3)

http://blog.csdn.net/aimingoo/archive/2009/09/08/4532496.aspx &#xff08;书接上回&#xff0c;继续&#xff01;&#xff09; 五、这个DSL框架有什么问题&#xff1f; 有什么问题吗&#xff1f;有一点&#xff0c;并不严重。比如说&#xff0c;我们在Env中声明了一些属性…

htop 命令详解

htop 官网&#xff1a;http://htop.sourceforge.net/ Linux top 命令的用法详细详解&#xff1a;https://www.cnblogs.com/zhoug2020/p/6336453.html htop 使用详解&#xff1a;https://www.cnblogs.com/programmer-tlh/p/11726016.html 使用 yum 无法直接安装 htop&#xff…

linux主机服务器日志采集,Linux通过Rsyslog搭建集中日志服务器

(一)Rsyslog简介ryslog 是一个快速处理收集系统日志的程序&#xff0c;提供了高性能、安全功能和模块化设计。rsyslog 是syslog 的升级版&#xff0c;它将多种来源输入输出转换结果到目的地。rsyslog是一个开源工具&#xff0c;被广泛用于Linux系统以通过TCP/UDP协议转发或接收…

IDC预测2022年全球智能家居连接设备市场规模将达10亿台!

来源&#xff1a; IDC官网、智慧生活&#xff1b; 物联网资本论编译摘要&#xff1a;2017年&#xff0c;全球智能家居连接设备市场规模达到43310万台&#xff0c;比上一年增长27.6&#xff05;。2022年市场达到9.397亿台&#xff0c;IDC预计复合年增长率&#xff08;CAGR&#…

Spring Data JPA 从入门到精通~方法的查询策略的属性表达式

方法的查询策略的属性表达式&#xff08;Property Expressions&#xff09; 属性表达式只能引用托管&#xff08;泛化&#xff09;实体的直接属性&#xff0c;如前一个示例所示。在查询创建时&#xff0c;已经确保解析的属性是托管实体的属性&#xff0c;但是&#xff0c;还可…

effective C++ 读书笔记

本篇文章都是摘自 《Effective C》 中文版 第三版 和 第二版。 再好的记性也有忘记的一天&#xff0c;记录下以备随时查看。。。 电子书下载地址&#xff1a;https://download.csdn.net/download/freeking101/10278088 《Effective C》第二版在线教程&#xff1a;http://www.…

抓取新浪的每日星座运势

从新浪上抓取每日的星座运势&#xff0c;然后往求实的Astrology版发. #!/usr/bin/python# encoding: utf-8from sgmllib import SGMLParserfrom datetime import datetime, timedeltaimport reimport urllibstarurlhttp://image2.sina.com.cn/ast/2007index/tmp/star_php/star.…

Spring Data JPA 从入门到精通~思维导图

#原图 System.out.println("https://www.processon.com/view/61c7227c0e3e7474fb9b4b76?fromnew1");

发邮件

System.Net.Mail.MailMessage message new System.Net.Mail.MailMessage("发件邮箱gmail.com","收件邮箱163.com", "测试标题", "测试内容"); System.Net.Mail.SmtpClient smtpClient new System.Net.Mail.SmtpClient("smtp.g…

Linux 编译 没有path,编译linux-2.6.21的问题-‘PATH_MAX’ undeclared

编译linux-2.6.21的问题&#xff1a;cripts/mod/sumversion.c: In function ‘get_src_version’:scripts/mod/sumversion.c:384: error: ‘PATH_MAX’ undeclared (first usein this function)scripts/mod/sumversion.c:384: error: (Each undeclared identifier isreported o…

高通5G版图现身!你的网络生活将迎来巨变?

来源&#xff1a;36Kr 作者&#xff1a;桐由于骁龙845移动平台和骁龙636移动平台的首发&#xff0c;3月的手机市场对于持币代购的消费者而言注定是充满期待的&#xff0c;在三星S9和红米Note5刷屏之时&#xff0c;曾经隐身手机幕后的高通也再一次引发用户热议&#xff0c;高通…

异步复位设计中的亚稳态问题及其解决方案

异步复位设计中的亚稳态问题及其解决方案田志明&#xff0c;杨军&#xff0c;罗岚&#xff08;东南大学国家专用集成电路系统工程技术研究中心&#xff0c;南京 210096&#xff09;摘 要&#xff1a;尽管异步复位是一种安全可靠复位电路的方法&#xff0c;但如果处理不当的话&a…

linux添加nginx,linux下安装Nginx1.16.0的教程详解

因为最近在倒腾linux&#xff0c;想安装新版本的nginx&#xff0c;找了一圈教程没有找到对应的教程&#xff0c;在稍微倒腾了一会之后终于成功的安装了最新版。服务器环境为centos&#xff0c;接下来是详细步骤&#xff1a;安装必要依赖插件?创建文件夹并切换过去?下载安装包…

深度|2030年8亿人会失业!图解机器人如何取代你的工作

来源&#xff1a;财看见-腾讯财经&#xff08;ID&#xff1a;qqckj2017&#xff09;未来智能实验室是人工智能学家与科学院相关机构联合成立的人工智能&#xff0c;互联网和脑科学交叉研究机构。未来智能实验室的主要工作包括&#xff1a;建立AI智能系统智商评测体系&#xff0…

Java使用Itext5.5.10进行pdf签章

来源&#xff1a;Java使用Itext5.5.10进行pdf签章_liumengya007007的博客-CSDN博客_itext 签章 啰嗦 说到PDF数字签名签章&#xff0c;这个其实也是数字证书信息安全的应用范畴&#xff0c;关于数字证书和数字签名&#xff0c;网上有很多解释说明&#xff0c;但讲解都多不够详…

Python的bool类型

写习惯了C#的代码&#xff0c;在想要将一个字符串False转换为bool型的时候&#xff0c;很自然的写了如下的Python代码&#xff1a; 看到上面的结果了没&#xff1f;是True。突然记起Python中除了、""、0、()、[]、{}、None为False之外&#xff0c;其他的都是True。也…