进程的启动与终止

进程的启动

当内核执行C程序时(使用exec函数)在调用main前先调用一个特殊的启动例程。可执行程序文件将此启动例程指定位程序的起始地址。启动例程从内核取得命令行参数和环境变量值,然后为按上述方式调用main函数做好安排。

进程的启动与终止_第1张图片
image.png

进程的终止

正常终止

  1. 从main返回
  2. 调用exit
  3. 调用_exit或_Exit
  4. 最后一个线程从其启动例程返回
  5. 从最后一个线程调用pthread_exit

异常终止

  1. 调用abort
  2. 接到一个信号
  3. 最后一个线程对取消请求做出响应
  • 进程通过main函数return返回,会调用C库中的exit函数,exit函数首先调用各终止处理函数,然后关闭(通过fclose)所有打开流,然后调用的_exit退出。
  • 如果直接调用_exit不会调用终止处理函数和关闭被打开的流。
  • 若程序调用exec函数族中的任一函数,则将清除所有已注册的终止处理函数。
  • 进程收到信号时,如果没有注册对应的信号处理函数,那么内核就会执行信号的默认动作,一般是直接终止进程。

1. 演示 return, exit, _exit 的区别

下面代码来源第5章 进程环境(2)_进程的启动和终止

#include 
#include 
#include 
#include 

void term_fun1(void){
    printf("first term function\n");
}

void term_fun2(void){
    printf("second term function\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(term_fun1);
    atexit(term_fun2);
    atexit(term_fun3);

    FILE *fp = fopen(argv[1], "w");
    fprintf(fp, "hello world!\n");

    if(!strcmp(argv[2], "exit")){
        exit(0);
    } 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");
    }

    return 0;
}
# return 调用终止处理程序,刷新标准I/O缓存
LEOQYANG-MC1:ch07 leoqyang$ ./process_term process_term.txt return 
third term function
second term function
first term function
LEOQYANG-MC1:ch07 leoqyang$ cat process_term.txt 
hello world!

# exit 调用终止处理程序,刷新标准I/O缓存
LEOQYANG-MC1:ch07 leoqyang$ ./process_term process_term.txt exit
third term function
second term function
first term function
LEOQYANG-MC1:ch07 leoqyang$ cat process_term.txt 
hello world!

# _exit 不执行终止处理程序,不刷新标准I/O缓存,直接退出
LEOQYANG-MC1:ch07 leoqyang$ ./process_term process_term.txt _exit
LEOQYANG-MC1:ch07 leoqyang$ cat process_term.txt 
LEOQYANG-MC1:ch07 leoqyang$ 

2. 演示收到信号的情况

#include 
#include 
#include 

static void callback(void){
    printf("callback\n");
}

int main(int argc, char * argv[]){
    if (argc < 2){
        fprintf(stderr, "usage: filename\n");
        exit(1);
    }

    FILE *fp = fopen(argv[1], "w");
    fprintf(fp, "hello world!\n");
    
    atexit(callback);

    while(1) {
        sleep(1);
    }

    

    printf("main exit\n");
    return 0;
}
# 执行killall 3_3_2 不执行终止处理程序,不刷新标准I/O缓存,直接退出
LEOQYANG-MC1:ch3 leoqyang$ ./3_3_2 3_3_2.txt
Terminated: 15
LEOQYANG-MC1:ch3 leoqyang$ cat 3_3_2.txt 
LEOQYANG-MC1:ch3 leoqyang$ 

参考

  • 第5章 进程环境(2)_进程的启动和终止
  • Unix环境高级教程 第7章
  • Linux环境编程 第3章

你可能感兴趣的:(进程的启动与终止)