Linux系统调用:进程的终止

之前总结了Linux的系统创建,主要是fork()函数和vfork()函数,最近总结了Linux进程的终止,主要的调用是_exit()和exit().

先看看两个函数的原型以及各自属于的头文件,可以发现这两个方法的区别

_exit()函数:

    #include <unistd.h>  

    void _exit(int status);  

从_exit()的头文件能够发现,_exit()是属于Linux的系统调用, 只能在Linux或者是Unix上才支持这个调用。

其中,status定了进程的终止状态,其父进程可以通过wait()函数来获取这个状态,从而进行之后的执行操作。当status为0时,表示进程正常退出,反之则是非正常退出。调用_exit()会使进程总是成功终止,也就是说_exit()方法从不会返回。

此处需要注意的是,虽然status定义成了整型,但实际上只有低8位可用,其原因就是当以信号(signal)终止一个进程的时候,shell会将变量$?置为128与信号之和,以表征这一事实。如果这与进程调用_exit()时所使用相同status值混杂起来,将令shell无法分辨。(这个地方不是很理解)

exit()函数:

#include <stdlib.h>  

void exit(int status); 

从exit()的头文件可以看出,exit()是C语言的库函数,所以所有的C语言都支持这个方法。

exit()在调用的时候要做得工作会比较多,主要有如下几个操作:

  1. 调用退出处理程序(通过atexit()和on_exit()注册的函数),并且在有多个退出处理程序时,执行顺序与注册顺序相反。
  2. 刷新stdio流缓冲区;
  3. 使用有status提供的值执行_exit()函数

我们通常在写程序的时候,在main()函数结尾只是用了return n;来结尾,在这个地方,return n; 就相当于exit(n),在结束的时候主函数会将返回值作为调用exit()函数的参数。这个地方本人有个疑问,在exit()函数调用_exit()时,其参数使用前面的n,而在_exit(int status)中,status为0表示程序正常结束,如果在return的时候,指定的n不为0,是一个其他的数,Linux内部会怎么处理呢?

其实在进程终止的时候,还有一些更细致的操作,由于本人目前能力有限,先不做讨论。

刚刚在前面提到了退出处理程序,现在来看看退出处理程序。

使用退出处理程序的原因就是,我们调用的exit()是C语言的库函数,而库函数对于进程的退出并没有实际控制的权利,所以无法在进程退出时调用系统特定的清理函数,所以退出处理函数就应运而生。

GUNC 提供了一下两种方式来注册退出处理函数:

    #include <stdlib.h>  

    int atexit(void (*func)(void));  

    //退出处理函数的定义  

    void func(void) {
        /* performance */
    }  

需要注意的是:

  1. atexit()函数在出错的时候返回的是非0值,不仅仅是负值;
  2. 同时,在退出处理函数中如果访问了此前mian()函数中本地变量,那么main()函数的返回会导致未定义的行为;
  3. 当有多个退出处理程序的时候,退出处理程序的调用顺序与之策顺序是相反的,这一点的逻辑是,先注册的通常是更为基本的清理动作,可能需要在后续注册的函数后再执行;
  4. 一旦退出处理程序在无法返回——调用了_exit()或者因为信号而终止,其后的处理程序将不再执行。

以上的atexit()有两个局限,第一是退出处理程序不能获取当前进程退出时的状态,而根据进程退出状态来做相应的操作可以是支持的;第二就是不能给退出处理程序传递参数。

所以glibc提供了一个非标准的替代方法:on_exit()。其定义如下:

    #define _BSD_SOURCE
    #include <stdlib.h>  

    int on_exit(void (*func)(int, void *),void *arg);  

    //退出处理函数定义
    void func(int status, void *arg) {
        /* Performace */
    }  

和atexit()函数类似,on_exit()的出错时返回值为非0。而on_exit()还不是所有标准都支持,还是应该尽量避免。

atexit()和on_exit()注册的函数属于同一个函数列表,在执行时与注册的顺序相反。

最后给一个例子仅供大家参考:

#define _BSD_SOURCE
#include <stdlib.h>
#include <sys/types.h>
#include <stdio.h>  

static void atexitFunc1(void) {
    printf("atexit function 1 called\n");
}  

static void atexitFunc2(void) {
    printf("atexit function 2 called\n");
}  

static void onexitFunc(int exitStatus, void *arg) {
    printf("on_exit function called: status=%d, arg=%ld\n",exitStatus, (long) arg);
}  

int main(int argc, char *argv[]) {
    if(on_exit(onexitFunc, (void *) 10) != 0)
        perror("on_exit 1");
    if(atexit(atexitFunc1) != 0)
        perror("atexit 1");
    if(atexit(atexitFunc2) != 0)
        perror("atexit 2");
    if(on_exit(onexitFunc, (void *) 10) != 0)
        perror("on_exit 2");
    exit(2);
} 

执行的结果如下:

    on_exit function called: status=2, arg=20
    atexit function 2 called
    atexit function 1 called
    on_exit function called: status=2, arg=10  

希望和大家多交流

时间: 2024-09-29 23:02:46

Linux系统调用:进程的终止的相关文章

Linux系统管理-进程管理-终止进程

主要是三个命令:kill ,killall,pkill 查看可用进程信号:

linux下查找进程及终止进程操作的相关命令

使用linux操作系统,难免遇到一些软件"卡壳"的问题,这时就需要使用linux下强大的kill命令来结束相关进程.这在linux系统下是极其容易的事情,你只需要kill xxx即可,这里xxx代表与此软件运行相关的进程PID号.首先,我们需要使用linux下另外一个命令ps查找与进程相关的PID号:ps aux | grep program_filter_word1)ps a 显示现行终端机下的所有程序,包括其他用户的程序.2)ps -A 显示所有程序.3)ps c 列出程序时,显示

windows系统调用 进程终止

1 #include "windows.h" 2 #include "iostream" 3 #include "stdio.h" 4 using namespace std; 5 6 static LPCTSTR q_szMutexName="w2kdg.ProcTerm.mutex.Suicide"; 7 8 HANDLE StartClone(){ 9 TCHAR szFilename[MAX_PATH]; 10 Get

我使用过的Linux命令之kill - 终止进程/发送信号

用途说明 kill命令用于终止指定的进程(terminate a process),是Unix/Linux下进程管理的常用命令.通常,我们在需要终止某个或某些进程时,先使用ps/pidof/pstree/top等工具获取进程PID,然后使用kill命令来杀掉该进程.kill命令的另外一个用途就是向指定的进程或进程组发送信号(The  command kill sends the specified signal to the specified process or process group)

Linux之进程终止

Linux中进程退出分为正常退出和异常退出 1.正常退出 (1)在main()函数中执行return (2)调用exit()函数 (3)调用_exit()函数 2.异常退出 (1)调用about()函数 (2)进程收到某个信号,而该信号使进程终止 对比 (1)exit与return exit:一个函数,有参数.exit执行完后把控制权交给系统 return:函数执行完后的返回.return执行完后把控制权交给调用函数 (2)exit与about exit:正常终止进程 about:异常终止进程

Linux命令:kill命令 终止进程

Linux中的kill命令用来终止指定的进程(terminate a process)的运行 通常,终止一个前台进程可以使用Ctrl+C键,但是,对于一个后台进程就须用kill命令来终止,我们就需要先使用ps/pidof/pstree/top等工具获取进程PID,然后使用kill命令来杀掉该进程.kill命令是通过向进程发送指定的信号来结束相应进程的.在默认情况下,采用编号为15的TERM信号.TERM信号将终止所有不能捕获该信号的进程.对于那些可以捕获该信号的进程就要用编号为9的kill信号,

Linux系统调用列表(转)

以下是Linux系统调用的一个列表,包含了大部分常用系统调用和由系统调用派生出的的函数.这可能是你在互联网上所能看到的唯一一篇中文注释的Linux系统调用列表,即使是简单的字母序英文列表,能做到这么完全也是很罕见的. 按照惯例,这个列表以man pages第2节,即系统调用节为蓝本.按照笔者的理解,对其作了大致的分类,同时也作了一些小小的修改,删去了几个仅供内核使用,不允许用户调用的系统调用,对个别本人稍觉不妥的地方作了一些小的修改,并对所有列出的系统调用附上简要注释. 其中有一些函数的作用完全

[Linux]Linux系统调用列表

本文列出了大部分常见的Linux系统调用,并附有简要中文说明. 以下是Linux系统调用的一个列表,包含了大部分常用系统调用和由系统调用派生出的的函数.这可能是你在互联网上所能看到的唯一一篇中文注释的Linux系统调用列表,即使是简单的字母序英文列表,能做到这么完全也是很罕见的. 按照惯例,这个列表以man pages第2节,即系统调用节为蓝本.按照笔者的理解,对其作了大致的分类,同时也作了一些小小的修改,删去了几个仅供内核使用,不允许用户调用的系统调用,对个别本人稍觉不妥的地方作了一些小的修改

[Linux]系统调用理解(2)

本文介绍了Linux下的进程概念,并着重讲解了与Linux进程管理相关的4个重要系统调用getpid,fork,exit和_exit,辅助一些例程说明了它们的特点和使用方法. 关于进程的一些必要知识 先看一下进程在大学课本里的标准定义:“进程是可并发执行的程序在一个数据集合上的运行过程.”这个定义非常严谨,而且难懂,如果你没有一下子理解这句话,就不妨看看笔者自己的并不严谨的解释.我们大家都知道,硬盘上的一个可执行文件经常被称作程序,在Linux系统中,当一个程序开始执行后,在开始执行到执行完毕退