第5章 进程环境(2)_进程的启动和终止

2. 进程启动和终止

2.1 C程序启动过程

(1)启动例程

  ①是一段程序代码,放置在/lib/libc.so.***中。编译器在编译时会将启动例程的代码编译进可执行文件中

  ②可执行程序将这段嵌入的启动例代码指代为程序的起始地址

  ③当内核执行C程序时(使用exec函数),在调用main前先执行启动例程代码

(2)启动例程的作用

  ①搜集命令行的参数传递给main函数中的argc和argv

  ②搜集环境信息构建环境表并传递给main函数

  ③登记进程的终止函数

2.2 进程终止

 


进程终止


主要方式


正常终止


①从main函数返回;②调用exit(标准C库函数);

③调用_exit或_Exit(系统调用);

④最后一个线程从其启动例程返回。

⑤最后一个线程调用pthread_exit


异常终止


①调用abort;②接到一个信号并终止;

③最后一个线程对取消请求做出响应


进程返回


①通常程序运行成功返回0,否则返回非0。②在shell中可以通过echo $?查看进程返回值

2.3 相关函数

(1)exit函数


头文件


#include<stdlib.h>


函数


void exit(int status);  

void _Exit(int status);

void _exit(int status); //#include <unistd.h>


功能


终止进程


备注


(1)_exit和_Exit立即进入内核

(2)exit会先执行一些清理处理(包括调用执行各终止处理程序,关闭所有标准I/O流等),然后再进入内核

(2)atexit函数


头文件


#include<stdlib.h>


函数


int atexit(void(*function)(void));


返回值


若成功则为0,若出错则为-1


功能


向内核登记终止处理程序(exit handler)


备注


(1)每个启动的进程都默认登记了一个标准的终止函数。

(2)终止函数在进程终止时释放进程所占用的一些资源。

(3)登记的多个终止函数执行顺序以栈的方式执行的,即先登记的后执行

【编程实验】终止处理函数

//process_term.c

#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

//定义进程的终止函数
void term_fun1(void)
{
    printf("first term function\n");
}

void term_fun2(void)
{
    printf("second term funciton\n");
}

void term_fun3(void)
{
    printf("third term function\n");
}

int main(int argc, char* argv[])
{
    if(argc < 3){
        fprintf(stderr, "usage: %s file [exit|_exit|return]\n");
        exit(1);
    }    

    //调用atexit函数向内核登记终止函数
    //注意:注册终止函数的顺序为func1->fun2->fun3,函数被调用顺序fun3->fun2->fun1
    atexit(term_fun1);
    atexit(term_fun2);
    atexit(term_fun3);

    FILE* fp = fopen(argv[1], "w");
    fprintf(fp, "hello world!\n"); //fprintf带缓存,调用exit或return时会被
                                   //流会被关闭,即会被写入指定的文件中。

    if(!strcmp(argv[2], "exit")){
        exit(0);   //标准C的库函数
    }else if(!strcmp(argv[2], "_exit")){
        _exit(0);  //系统调用
    }else if(!strcmp(argv[2], "return")){
        return 0;
    }else{
        fprintf(stderr, "usage: %s file [exit|_exit|return]\n", argv[0]);
    }

    return 0;
}
/*输出结果:
[[email protected] 5.process]# bin/process_term term.txt return  //正常退出(调用终止函数和刷新缓存)
third term function
second term funciton
first term function
[[email protected] 5.process]# cat term.txt
hello world!
[[email protected] 5.process]# bin/process_term term.txt exit   //正常退出(调用终止函数和刷新缓存)
third term function
second term funciton
first term function
[[email protected] 5.process]# cat term.txt
hello world!
[[email protected] 5.process]# bin/process_term term.txt _exit //异常退出(不调用终止函数和刷新缓存)
[[email protected] 5.process]# cat term.txt
[[email protected] 5.process]# bin/process_term term.txt quit
usage: bin/process_term file [exit|_exit|return]
third term function
second term funciton
first term function
[[email protected] 5.process]# cat term.txt
hello world!
[[email protected] 5.process]#
 */

2.4 C程序的启动和终止

(1)进程的终止

(2)终止方式的区别


return


exit()


_exit/_Exit


是否刷 新标准I/O缓存





是否自动调用终止函数




(3)说明

  ①exit首先调用各终止处理程序,然后按需要多次调用fclose关闭所有打开流。而调用_exit或_Exit则将直接进入内核,不会调用终止处理函数和关闭被打开的流。

  ②POSIX标准规定,如果程序调用exec函数族中的任一个函数,则将清除所有己安装的终止处理程序。

  ③内核使程序执行的唯一方法是调用一个exec函数。进程自愿终止的唯一方未能是显式或隐式地(通过调用exit)来调用_exit或_Exit。进程序也可以非自愿地由一个信号使其终止。

时间: 2024-10-11 13:16:57

第5章 进程环境(2)_进程的启动和终止的相关文章

linux_c开发(5-1)进程间通讯_进程间通讯概念

目的:为什么进程间需要通信? 1.数据传输 一个进程需要将他的数据发送给另外一个进程. 2.资源共享 多进程之间共享同样的资源. 3.通知事件 一个进程需要向另一个或一组进程发送消息,通知他们发生了某种事件. 4.进程控制 有些进程希望完全控制另一个进程的执行(eg:debug进程),此时控制进程希望能够拦截另一个进程的所有操作,并能够及时知道他的状态改变. 发展: linux进程间通讯(IPC)由以下及部分发展而来: 1.UNIX间进程通讯 2.基于system v进程间通讯 3.POSIX进

第5章 进程环境(1)_进程结构(task_struct)

1. 进程的概念和进程结构 1.1 进程 (1)程序(program):是一些保存在磁盘上有序指令的集合,是存放在磁盘文件中的可执行文件.但没有任何执行的概念,它是静态的. (2)进程(process) ①程序的执行实例被称为进程,是一个动态的概念,它是程序执行的过程,包括创建.调度和消亡. ②进程具有独立的权限与职责,如果系统中某个进程崩溃,它不会影响其余的进程. ③每个进程运行在其各自的虚拟地址空间中,进程之间可以通过由内核控制的机制相互通信. (3)进程ID:每个linux进程都有一个唯一

《Unix环境高级编程》读书笔记 第7章-进程环境

1. main函数 int main( int argc, char *argv[] ); argc是命令行参数的数目,包括程序名在内 argv是指向参数的各个指针所构成的数组,即指针数组 当内核执行C程序时(使用exec函数),在调用main前先调用一个特殊的启动例程.可执行程序文件将此启动例程指定为程序的起始地址——这是由连接器设置的,而连接器则是由C编译器调用.启动例程从内核取得命令行参数和环境变量值,然后按上述方式调用main函数做好安排. 2. 进程终止 有8种方式使进程终止,其中5种

Unix编程第7章 进程环境

准备雄心勃勃的看完APUE,但是总感觉看着看着就像进入一本字典,很多地方都是介绍函数的用法的,但是给出例子远不及函数介绍的多.而且这本书还是个大部头呢.第7章的讲的进程环境,进程是程序设计中一个比较重要的概念,知道倒是知道它的大概意思,但是其实还是有很多的细节其实都没有深究,这章呢APUE就带着我们逛了一下如下的几个主题(尼玛,学C语言的话,学那点语法其实不是很重要,反而经常把时间浪费在语法的蹩脚处): 1.程序执行的时候main函数是如何被调用的 2.命令行参数是如何传递给新程序的: 3.典型

APUE学习笔记:第七章 进程环境

7.1 引言 本章将学习:当执行程序时,其main函数是如何被调用的:命令行参数是如何传送给执行程序的:典型的存储器布局是什么样式:如何分配另外的存储空间:进程如何使用环境变量:各种不同的进程终止方式等:另外还将说明longjmp和setjmp函数以及它们与栈的交互作用:还将介绍研究进程的资源限制 7.2 main函数 C程序总是从main函数开始执行.当内核执行C程序时,在调用main前先调用一个特殊的启动例程.可执行程序文件将此启动例程指定为程序的起始地址——这是由连接编辑器设置的,而连接编

第7章 进程环境

main函数 main函数之前会有一个特殊的启动程序,启动例程从内核取得命令行参数和环境变量. 进程终止 正常终止: 从main函数返回 调用exit 调用_exit或_Exit 最后一个线程从启动例程返回 最后一个线程调用pthread_exit 异常终止: 调用abort 接到一个信号终止 最后一个线程对取消请求作出相应 exit函数 _exit和_Exit直接进入内核,exit则先执行一系列清理处理(调用终止处理程序,关闭所有标准io流),然后进入内核 #include<stdlib.h>

第七章:进程环境

一.进程终止 进程正常终止: 1. 从main()函数返回,即retrun 0 2. 调用exit(),即在main()函数内或其它被main()函数调用的函数内调用exit() 3. 调用_exit()或_Exit(),即在main()函数内或其它会被main()调用的函数体内调用_exit()或_Exit() 4. 最后一个线程从其所在进程返回 5. 最后一个线程在其所在进程调用pthread_exit()函数 进程异常终止: 6.调用abort() 7.进程接收到信号 8.进程中最后一个线

第7章 进程关系(2)_进程链和进程扇

2. 进程链和进程扇 (1)创建进程链 ①进程链:就是父进程创建一个子进程,创建的子进程再次创建出属于自己的子进程,这样依次往下循环,如下图所示. ②关键实现:判断出如果是父进程则退出,保证父进程只会创建一个子进程.如果是子进程继续创建接下来的进程再退出. [编程实验]构建进程链 //process_link.c #include <unistd.h> #include <stdio.h> #include <stdlib.h> int main(int argc, c

读书笔记-APUE第三版-(7)进程环境

本章关注单进程运行环境:启动&终止.参数传递和内存布局等. 进程启动终止 如图所示: 启动:内核通过exec函数执行程序,在main函数运行之前,会调用启动例程(start-up routine),取得命令行参数和环境变量.可以把启动例程理解为exit(main(argc,argv)). 终止:五种正常终止方式(从main方法返回/exit/_exit/最后一个线程返回/最后一个线程退出):三种异常终止方式(abort/接收到信号/最后一个线程接收到取消请求). exit与_exit关系:exi