《Linux从小白到高手》理论篇(八):Linux的进程管理详解

本篇将介绍Linux的进程管理相关知识,并将深入介绍Linux的进程间相互通信。

进程就是运行中的程序,一个运行着的程序,可能有多个进程。 比如Oracle DB,启动Oracle实例服务后,就会有多个进程。

Linux进程分类

在 Linux 系统中,进程可以分为以下几类:

1、用户进程和系统进程

用户进程:

--由用户启动的应用程序或服务,例如文本编辑器、浏览器、数据库客户端等。

--这些进程在用户的权限下运行,通常只能访问用户自己的数据和资源。

--用户进程的优先级相对较低,系统会根据资源的可用性和其他因素来调度它们的执行。

系统进程:

--由操作系统内核启动的进程,用于管理系统资源、提供服务和执行系统级任务。例如,init进程(或systemd进程)是系统启动时第一个运行的进程,负责启动其他系统服务和管理系统的运行状态。

--系统进程通常具有较高的优先级,以确保系统的稳定运行和对关键任务的响应。

2、前台进程和后台进程

前台进程:

--与用户交互的进程,通常在终端窗口中运行,接收用户的输入并显示输出。例如,当你在终端中运行一个命令时,该命令对应的进程就是前台进程,直到它执行完毕或被中断,终端窗口才会恢复可用状态。

后台进程:

--在后台运行的进程,不与用户直接交互,可以在终端窗口继续执行其他命令的同时运行。

--可以通过在命令末尾加上 "&" 符号来将一个进程放入后台运行。例如,command &。

--后台进程通常用于执行长时间运行的任务,如数据备份、文件下载等,不会阻塞终端的使用。

3、守护进程(Daemon)

定义和特点:

--守护进程是在后台持续运行的特殊进程,通常在系统启动时自动启动,并一直运行直到系统关闭。

--它们不与终端关联,独立于用户登录和注销,负责执行特定的系统任务或提供特定的服务。

--守护进程通常具有较高的稳定性和可靠性,能够在系统运行过程中持续提供服务,不受用户交互的影响。

常见的守护进程:

httpd:Web 服务器守护进程,用于提供 HTTP 服务。

sshd:SSH 服务器守护进程,允许远程用户通过 SSH 协议登录到系统。

crond:定时任务守护进程,负责按照预定的时间表执行任务。

syslogd:系统日志守护进程,记录系统中的各种事件和消息。

4、孤儿进程和僵尸进程

孤儿进程:

--当一个父进程先于其子进程结束时,子进程就成为孤儿进程。

--孤儿进程会被init进程(或systemd进程)收养,由init进程负责管理它们的资源和状态。

僵尸进程:

--当一个子进程结束时,它的资源并不会立即被释放,而是会保留一些状态信息,直到父进程读取这些信息为止。在这个期间,子进程就成为僵尸进程。

--如果父进程没有正确地处理子进程的结束状态,僵尸进程可能会一直存在,占用系统资源。

可以使用ps或者top命令查看僵尸进程,其状态通常显示为 "Z"。

进程的属性

进程具有以下一些主要属性:

1、进程标识符(PID)

定义:每个进程都有唯一的进程标识符(Process ID,PID),用于在系统中标识该进程。

作用:操作系统通过 PID 来区分不同的进程,进行进程管理和调度。例如,使用命令如 ps、top、kill 等时,通常需要指定进程的 PID。

2、父进程标识符(PPID)

定义:每个进程都有一个父进程,除了初始进程(通常是 init 进程或 systemd 进程)。父进程标识符(Parent Process ID,PPID)用于标识创建当前进程的父进程。

作用:可以通过 PPID 来追踪进程的创建关系,了解进程的层次结构。在故障排除时,有时可以通过查看父进程的行为来确定子进程出现问题的原因。

3、进程状态

运行状态(Running):进程正在被 CPU 执行。

就绪状态(Ready):进程已经准备好被 CPU 执行,等待分配 CPU 时间片。

睡眠状态(Sleeping):进程处于等待状态,例如等待 I/O 操作完成、等待信号等。睡眠状态又分为可中断睡眠(Interruptible Sleep)和不可中断睡眠(Uninterruptible Sleep)。

停止状态(Stopped):进程被暂停,通常是由于接收到信号,如 SIGSTOP。

僵尸状态(Zombie):子进程已经结束,但父进程还没有回收其资源,处于僵尸状态的进程只保留一些退出信息,等待父进程读取。

4、优先级

定义:进程的优先级决定了它在系统中获得 CPU 时间片的机会。优先级高的进程会优先被调度执行。

调整:可以使用命令如 nice 和 renice 来调整进程的优先级。优先级数值越低,优先级越高。例如,nice -n -10 command 以较高优先级启动一个命令,renice -n 5 -p PID 将进程的优先级调整为 5。

5、资源占用

CPU 占用:进程在运行时会占用 CPU 时间。可以通过工具如 top、htop 等查看进程的 CPU 占用率。

内存占用:进程会占用一定数量的内存空间,包括代码、数据、栈等。同样可以使用系统工具查看进程的内存使用情况。

文件描述符:进程可能会打开文件、网络连接等资源,这些资源通过文件描述符来表示。每个进程都有一定数量的文件描述符可用。

6、环境变量

定义:进程在运行时可以访问一组环境变量,这些变量包含了关于系统和用户配置的信息。

作用:环境变量可以影响进程的行为,例如指定程序的搜索路径、配置数据库连接参数等。可以通过命令 env 查看当前进程的环境变量,也可以在启动进程时设置特定的环境变量。

7、命令行参数

定义:当启动一个进程时,可以传递一些命令行参数给它。这些参数可以影响进程的行为和功能。

作用:例如,一个文本编辑器可以接受文件名作为命令行参数,直接打开指定的文件。命令行参数可以让进程更加灵活地适应不同的使用场景。

父进程和子进程

为什么要把父进程和子进程单独拿出讲,因为很重要啦,父进程和子进程是进程关系中的重要概念。

1、父进程与子进程的创建

当一个进程使用特定的系统调用(如 fork)时,它可以创建一个新的进程,即子进程。这个新创建的子进程几乎是父进程的一个副本,包括代码、数据、打开的文件描述符等。

例如,以下是一个使用 C 语言创建子进程的示例代码:

2、资源共享与独立性

资源共享:

--子进程继承了父进程的许多属性,但也有一定的独立性。子进程会继承父进程打开的文件描述符,这意味着如果父进程打开了一个文件,子进程也可以访问这个文件。

--然而,子进程对文件描述符的操作(如读取、写入、关闭)不会影响父进程,除非进行了特定的同步操作。

独立性:

--子进程有自己的内存空间、寄存器状态等。虽然子进程开始时与父进程的内存内容相同,但后续的修改是独立的。

--子进程的运行不会影响父进程的执行,除非通过特定的进程间通信机制(如管道、信号、共享内存等)进行交互。

3、父子进程的关系管理

父进程责任:

--通常,父进程负责创建和监控子进程。父进程可以通过系统调用(如 wait 或 waitpid)等待子进程结束,并获取子进程的退出状态。

--如果父进程没有正确地等待子进程结束,子进程可能会成为僵尸进程,占用系统资源。

子进程行为:

--子进程可以独立地执行自己的任务。它可以根据需要修改自己的状态和资源,而不会直接影响父进程。

--子进程可以通过 exec 系列函数加载新的程序,替换自己的代码和数据,从而执行不同的任务。

4、应用场景

并发执行任务:

父进程可以创建多个子进程,让它们同时执行不同的任务,以提高系统的并行性和效率。例如,在服务器应用中,父进程可以创建多个子进程来处理客户端请求。

资源管理:

父进程可以控制子进程的资源分配和使用。例如,父进程可以限制子进程的 CPU 时间、内存使用等,以确保系统的稳定性和公平性。

进程间通信:

父子进程可以通过特定的进程间通信机制进行交互,共享数据和状态信息。例如,通过管道可以在父子进程之间传递数据。

linux进程通信(IPC,Inter - Process Communication)

在 Linux 中,进程通信有多种方式,以下是常见的几种:

管道(Pipe)

--定义和原理:管道是一种半双工的通信方式,数据只能单向流动,通常用于具有亲缘关系(如父子进程)的进程之间通信。它是基于文件描述符来实现的,通过内核缓冲区来传递数据。

--使用方法:通过pipe()系统调用创建管道,会返回两个文件描述符,一个用于读,一个用于写。例如,在父子进程通信中,父进程可以通过fork()创建子进程后,关闭不需要的文件描述符端,然后通过write()向管道写入数据,子进程通过read()从管道读取数据。

命名管道(FIFO)

--定义和原理:命名管道克服了管道只能用于亲缘关系进程的限制,它是一种特殊类型的文件,在文件系统中有一个文件名,可以被多个无亲缘关系的进程访问。其通信原理也是基于内核缓冲区。

--使用方法:可以使用mkfifo()系统调用来创建命名管道。一个进程以写方式打开命名管道,另一个进程以读方式打开命名管道,这样就可以实现通信。例如,进程 A 通过open("myfifo", O_WRONLY)打开命名管道用于写数据,进程 B 通过open("myfifo", O_RDONLY)打开用于读数据。

消息队列(Message Queue)

--定义和原理:消息队列是一个由内核维护的消息链表,消息被组织成一个个独立的数据单元,每个消息有自己的类型。进程可以向消息队列发送消息,也可以从消息队列接收消息,消息的发送和接收是异步的。

--使用方法:首先通过msgget()系统调用创建或获取一个消息队列标识符。然后通过msgsnd()发送消息,消息是一个包含消息类型和消息内容的结构体。接收消息使用msgrcv(),可以根据消息类型有选择地接收消息。

共享内存(Shared Memory)

--定义和原理:共享内存是最快的进程通信方式,它允许两个或多个进程共享一块内存区域。这些进程可以直接读写这块共享内存,就像访问自己的内存空间一样,减少了数据复制的开销。不过这种方式需要注意进程之间的同步和互斥问题。

--使用方法:使用shmget()系统调用创建或获取共享内存段的标识符。通过shmat()将共享内存段连接到进程的地址空间,使进程可以访问共享内存。进程使用完共享内存后,通过shmdt()分离共享内存段,最后通过shmctl()进行共享内存段的控制,如标记为删除等操作。

信号量(Semaphore)

--定义和原理:信号量主要用于实现进程之间的同步和互斥,它是一个计数器,用于控制对共享资源的访问。当信号量的值大于 0 时,表示资源可用;当信号量的值等于 0 时,表示资源已被占用。

--使用方法:通过semget()系统调用创建或获取信号量集的标识符。使用semctl()对信号量进行初始化和控制操作。进程在访问共享资源之前,通过semop()操作信号量,根据信号量的值来判断是否可以访问资源。

信号(Signal)

定义和原理:信号是一种异步通信机制,用于通知进程某个事件的发生。例如,当用户按下 Ctrl + C 时,会向当前进程发送一个SIGINT信号,进程收到信号后可以采取相应的措施,如终止进程或执行特定的信号处理函数。

使用方法:可以使用signal()或sigaction()系统调用来设置信号的处理函数。当信号产生时,内核会中断进程的正常执行流程,转而执行信号处理函数。

注:Linux进程间通讯比较复杂,更深层次的介绍需要阅读源码来解读,超出了本节的范畴。

进程的管理命令

Linux的进程管理命令有很多,限于篇幅和常用性,在次重点介绍最常用的三个:top/ps/pstree。其他命令会在文末附上,方便大家查询使用。

top

top命令是一个用于实时监控系统进程和资源使用情况的强大工具。

1、top命令的输出内容

启动top:在终端中输入top并回车,即可启动top命令。它会显示系统中正在运行的进程列表,以及系统的整体资源使用情况。

进程列表信息:

PID:进程标识符。

USER:进程所有者。

PR:进程优先级。

NI:进程的 nice 值,用于调整优先级。

VIRT:进程使用的虚拟内存大小。

RES:进程使用的物理内存大小。

SHR:进程共享的内存大小。

S:进程状态,如R(运行中)、S(睡眠中)、Z(僵尸状态)等。

%CPU:进程占用的 CPU 百分比。

%MEM:进程占用的内存百分比。

TIME+:进程使用的 CPU 时间。

COMMAND:启动进程的命令。

系统资源信息:

top命令顶部显示了系统的整体资源使用情况,包括:

Tasks:总进程数、正在运行的进程数、睡眠中的进程数等。

Cpu(s):CPU 使用率,包括用户空间、系统空间、空闲时间等的百分比。

Mem:内存使用情况,包括总内存、已使用内存、空闲内存等。

Swap:交换空间使用情况。

2、交互操作

排序:

按P键可以按照 CPU 使用率对进程列表进行排序,从高到低显示占用 CPU 最多的进程。

按M键可以按照内存使用率对进程列表进行排序。

刷新:

默认情况下,top会定期自动刷新显示。也可以按空格键手动刷新。

退出:

按q键可以退出top命令。

查看特定进程:

在top运行时,可以输入进程的 PID,然后按回车键,即可聚焦显示该特定进程的信息。

切换显示模式:

按l键可以切换显示平均负载和任务数。

按t键可以切换显示进程的 CPU 时间和累计时间。

改变更新频率:

按s键可以设置top的更新频率,输入一个数字表示更新时间间隔(以秒为单位)。

3、高级用法

命令行参数:

top -b:

以批处理模式运行top,不显示交互界面,适合将输出重定向到文件或其他程序进行分析。

top -n 10:

只显示 10 次更新,然后自动退出。

top -d 5:

设置更新时间间隔为 5 秒。

过滤进程:

在top运行时,可以输入/后跟一个关键字,如进程名称或用户名称,来过滤显示的进程列表。例如,输入/firefox可以只显示与 Firefox 相关的进程。

保存配置:

top的一些配置可以保存在用户的~/.toprc文件中,以便下次启动时自动应用这些配置。例如,可以设置默认的排序方式、更新频率等。

PS

ps(process status)命令用于显示当前系统中的进程状态。

1、基本用法

显示当前用户的进程:

ps:默认情况下,只显示当前用户在当前终端中启动的进程。

显示所有用户的进程:

ps -ef:

以全格式显示系统中的所有进程信息,包括进程的用户、PID、PPID、CPU 使用率、内存使用情况、启动时间、命令等。

ps aux:

也显示系统中的所有进程信息,但输出格式略有不同,更易读,通常和grep及管道命令搭配使用以提高效率。

2、输出字段解释

UID:进程所有者的用户 ID。

PID:进程标识符。

PPID:父进程标识符。

C:CPU 使用率。

STIME:进程启动时间。

TTY:控制终端的设备名称。

TIME:进程使用的 CPU 时间。

CMD:启动进程的命令。

3、筛选特定进程

根据 PID 筛选:

ps -p PID:

显示指定 PID 的进程信息。可以指定多个 PID,用逗号分隔。例如,ps -p 1234,5678。

根据进程名称筛选:

ps -C process_name

显示指定名称的进程信息。例如,ps -C firefox显示所有与 Firefox 相关的进程。

根据用户筛选:

ps -u username:

显示指定用户的进程信息。例如,ps -u john显示用户 john 拥有的进程。

4、输出格式控制

自定义输出字段:

ps -o field1,field2,...:

指定要显示的字段。例如,ps -o pid,cmd只显示进程 ID 和命令。

以树形结构显示进程关系:

ps -ef --forest:

以树形结构显示进程的父子关系,更直观地看出进程的层次结构。

5、高级用法

结合其他命令使用:

可以将ps的输出作为其他命令的输入,进行进一步的处理。例如,ps -ef | grep process_name可以查找特定名称的进程。

ps -ef | awk '{print $2}'

可以提取所有进程的 PID。

实时监控进程:

watch -n 1 'ps -ef':

每 1 秒执行一次ps -ef命令,实时监控系统中的进程变化。

按特定条件排序:

ps -ef --sort=-pcpu:

按 CPU 使用率从高到低排序显示进程。可以使用不同的排序字段,如-pmem按内存使用率排序。

pstree

pstree命令用于以树形结构显示进程之间的关系。

1、基本用法

显示所有进程的树形结构:

pstree:默认情况下,以树形结构显示系统中所有进程的关系,每个进程用进程名称表示,父进程和子进程之间用连线连接。

显示特定用户的进程树:

pstree -u username:显示指定用户的进程树。例如,pstree -u john显示用户 john 拥有的进程及其关系。

2、输出格式控制

显示进程 PID:

pstree -p:在进程名称后面显示进程的 PID。例如,init(1)-±acpid(2777)表示进程init的 PID 是 1,acpid的 PID 是 2777。

显示完整命令行:

pstree -a:在进程名称后面显示完整的命令行参数。这对于了解进程的具体启动参数很有帮助。

同时显示 PID 和完整命令行:

pstree -ap:结合了上述两种选项,既显示进程 PID,又显示完整命令行。

3、高级用法

过滤特定进程:

pstree | grep process_name:

可以使用管道将pstree的输出传递给grep命令,以过滤显示特定进程及其子进程。例如,pstree | grep firefox显示与 Firefox 相关的进程树。

以特定格式输出:

pstree -A:以 ASCII 艺术形式显示进程树,更加美观。但这种格式可能在某些终端中显示不完整。

pstree -G:以不同的颜色显示不同类型的进程,增强可读性。但需要终端支持颜色显示。

结合其他工具使用:

可以将pstree的输出重定向到文件,以便进一步分析。例如,pstree > process_tree.txt将进程树保存到文件中。

也可以在脚本中使用pstree来获取进程信息,进行自动化的系统管理任务。

附:进程管理命令大全(95%以上)

进程管理相关命令{

    ps -eaf               # 查看所有进程
    kill -9 PID           # 强制终止某个PID进程
    kill -15 PID          # 安全退出 需程序内部处理信号
    cmd &                 # 命令后台运行
    nohup cmd &           # 后台运行不受shell退出影响
    ctrl+z                # 将前台放入后台(暂停)
    jobs                  # 查看后台运行程序
    bg 2                  # 启动后台暂停进程
    fg 2                  # 调回后台进程
    pstree                # 进程树
    vmstat 1 9            # 每隔一秒报告系统性能信息9次
    sar                   # 查看cpu等状态
    lsof file             # 显示打开指定文件的所有进程
    lsof -i:32768         # 查看端口的进程
    renice +1 180         # 把180号进程的优先级加1
    exec sh a.sh          # 子进程替换原来程序的pid, 避免supervisor无法强制杀死进程

    ps{

        ps aux |grep -v USER | sort -nk +4 | tail       # 显示消耗内存最多的10个运行中的进程,以内存使用量排序.cpu +3
        # USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
        %CPU     # 进程的cpu占用率
        %MEM     # 进程的内存占用率
        VSZ      # 进程虚拟大小,单位K(即总占用内存大小,包括真实内存和虚拟内存)
        RSS      # 进程使用的驻留集大小即实际物理内存大小
        START    # 进程启动时间和日期
        占用的虚拟内存大小 = VSZ - RSS

        ps -eo pid,lstart,etime,args         # 查看进程启动时间

    }

    top{

        前五行是系统整体的统计信息。
        第一行: 任务队列信息,同 uptime 命令的执行结果。内容如下:
            01:06:48 当前时间
            up 1:22 系统运行时间,格式为时:分
            1 user 当前登录用户数
            load average: 0.06, 0.60, 0.48 系统负载,即任务队列的平均长度。
            三个数值分别为 1分钟、5分钟、15分钟前到现在的平均值。

        第二、三行:为进程和CPU的信息。当有多个CPU时,这些内容可能会超过两行。内容如下:
            Tasks: 29 total 进程总数
            1 running 正在运行的进程数
            28 sleeping 睡眠的进程数
            0 stopped 停止的进程数
            0 zombie 僵尸进程数
            Cpu(s): 0.3% us 用户空间占用CPU百分比
            1.0% sy 内核空间占用CPU百分比
            0.0% ni 用户进程空间内改变过优先级的进程占用CPU百分比
            98.7% id 空闲CPU百分比
            0.0% wa 等待输入输出的CPU时间百分比
            0.0% hi
            0.0% si

        第四、五行:为内存信息。内容如下:
            Mem: 191272k total 物理内存总量
            173656k used 使用的物理内存总量
            17616k free 空闲内存总量
            22052k buffers 用作内核缓存的内存量
            Swap: 192772k total 交换区总量
            0k used 使用的交换区总量
            192772k free 空闲交换区总量
            123988k cached 缓冲的交换区总量。
            内存中的内容被换出到交换区,而后又被换入到内存,但使用过的交换区尚未被覆盖,
            该数值即为这些内容已存在于内存中的交换区的大小。
            相应的内存再次被换出时可不必再对交换区写入。

        进程信息区,各列的含义如下:  # 显示各个进程的详细信息

        序号 列名    含义
        a   PID      进程id
        b   PPID     父进程id
        c   RUSER    Real user name
        d   UID      进程所有者的用户id
        e   USER     进程所有者的用户名
        f   GROUP    进程所有者的组名
        g   TTY      启动进程的终端名。不是从终端启动的进程则显示为 ?
        h   PR       优先级
        i   NI       nice值。负值表示高优先级,正值表示低优先级
        j   P        最后使用的CPU,仅在多CPU环境下有意义
        k   %CPU     上次更新到现在的CPU时间占用百分比
        l   TIME     进程使用的CPU时间总计,单位秒
        m   TIME+    进程使用的CPU时间总计,单位1/100秒
        n   %MEM     进程使用的物理内存百分比
        o   VIRT     进程使用的虚拟内存总量,单位kb。VIRT=SWAP+RES
        p   SWAP     进程使用的虚拟内存中,被换出的大小,单位kb。
        q   RES      进程使用的、未被换出的物理内存大小,单位kb。RES=CODE+DATA
        r   CODE     可执行代码占用的物理内存大小,单位kb
        s   DATA     可执行代码以外的部分(数据段+栈)占用的物理内存大小,单位kb
        t   SHR      共享内存大小,单位kb
        u   nFLT     页面错误次数
        v   nDRT     最后一次写入到现在,被修改过的页面数。
        w   S        进程状态。
            D=不可中断的睡眠状态
            R=运行
            S=睡眠
            T=跟踪/停止
            Z=僵尸进程 父进程在但并不等待子进程
        x   COMMAND  命令名/命令行
        y   WCHAN    若该进程在睡眠,则显示睡眠中的系统函数名
        z   Flags    任务标志,参考 sched.h

    }

    列出正在占用swap的进程{

        #!/bin/bash
        echo -e "PID\t\tSwap\t\tProc_Name"
        # 拿出/proc目录下所有以数字为名的目录(进程名是数字才是进程,其他如sys,net等存放的是其他信息)
        for pid in `ls -l /proc | grep ^d | awk '{ print $9 }'| grep -v [^0-9]`
        do
            # 让进程释放swap的方法只有一个:就是重启该进程。或者等其自动释放。放
            # 如果进程会自动释放,那么我们就不会写脚本来找他了,找他都是因为他没有自动释放。
            # 所以我们要列出占用swap并需要重启的进程,但是init这个进程是系统里所有进程的祖先进程
            # 重启init进程意味着重启系统,这是万万不可以的,所以就不必检测他了,以免对系统造成影响。
            if [ $pid -eq 1 ];then continue;fi
            grep -q "Swap" /proc/$pid/smaps 2>/dev/null
            if [ $? -eq 0 ];then
                swap=$(grep Swap /proc/$pid/smaps \
                    | gawk '{ sum+=$2;} END{ print sum }')
                proc_name=$(ps aux | grep -w "$pid" | grep -v grep \
                    | awk '{ for(i=11;i<=NF;i++){ printf("%s ",$i); }}')
                if [ $swap -gt 0 ];then
                    echo -e "${pid}\t${swap}\t${proc_name}"
                fi
            fi
        done | sort -k2 -n | awk -F'\t' '{
            pid[NR]=$1;
            size[NR]=$2;
            name[NR]=$3;
        }
        END{
            for(id=1;id<=length(pid);id++)
            {
                if(size[id]<1024)
                    printf("%-10s\t%15sKB\t%s\n",pid[id],size[id],name[id]);
                else if(size[id]<1048576)
                    printf("%-10s\t%15.2fMB\t%s\n",pid[id],size[id]/1024,name[id]);
                else
                    printf("%-10s\t%15.2fGB\t%s\n",pid[id],size[id]/1048576,name[id]);
            }
        }'

    }

    linux操作系统提供的信号{

        kill -l                    # 查看linux提供的信号
        trap "echo aaa"  2 3 15    # shell使用 trap 捕捉退出信号

        # 发送信号一般有两种原因:
        #   1(被动式)  内核检测到一个系统事件.例如子进程退出会像父进程发送SIGCHLD信号.键盘按下control+c会发送SIGINT信号
        #   2(主动式)  通过系统调用kill来向指定进程发送信号
        # 进程结束信号 SIGTERM 和 SIGKILL 的区别:  SIGTERM 比较友好,进程能捕捉这个信号,根据您的需要来关闭程序。在关闭程序之前,您可以结束打开的记录文件和完成正在做的任务。在某些情况下,假如进程正在进行作业而且不能中断,那么进程可以忽略这个SIGTERM信号。
        # 如果一个进程收到一个SIGUSR1信号,然后执行信号绑定函数,第二个SIGUSR2信号又来了,第一个信号没有被处理完毕的话,第二个信号就会丢弃。

        SIGHUP  1          A     # 终端挂起或者控制进程终止
        SIGINT  2          A     # 键盘终端进程(如control+c)
        SIGQUIT 3          C     # 键盘的退出键被按下
        SIGILL  4          C     # 非法指令
        SIGABRT 6          C     # 由abort(3)发出的退出指令
        SIGFPE  8          C     # 浮点异常
        SIGKILL 9          AEF   # Kill信号  立刻停止
        SIGSEGV 11         C     # 无效的内存引用
        SIGPIPE 13         A     # 管道破裂: 写一个没有读端口的管道
        SIGALRM 14         A     # 闹钟信号 由alarm(2)发出的信号
        SIGTERM 15         A     # 终止信号,可让程序安全退出 kill -15
        SIGUSR1 30,10,16   A     # 用户自定义信号1
        SIGUSR2 31,12,17   A     # 用户自定义信号2
        SIGCHLD 20,17,18   B     # 子进程结束自动向父进程发送SIGCHLD信号
        SIGCONT 19,18,25         # 进程继续(曾被停止的进程)
        SIGSTOP 17,19,23   DEF   # 终止进程
        SIGTSTP 18,20,24   D     # 控制终端(tty)上按下停止键
        SIGTTIN 21,21,26   D     # 后台进程企图从控制终端读
        SIGTTOU 22,22,27   D     # 后台进程企图从控制终端写

        缺省处理动作一项中的字母含义如下:
            A  缺省的动作是终止进程
            B  缺省的动作是忽略此信号,将该信号丢弃,不做处理
            C  缺省的动作是终止进程并进行内核映像转储(dump core),内核映像转储是指将进程数据在内存的映像和进程在内核结构中的部分内容以一定格式转储到文件系统,并且进程退出执行,这样做的好处是为程序员提供了方便,使得他们可以得到进程当时执行时的数据值,允许他们确定转储的原因,并且可以调试他们的程序。
            D  缺省的动作是停止进程,进入停止状况以后还能重新进行下去,一般是在调试的过程中(例如ptrace系统调用)
            E  信号不能被捕获
            F  信号不能被忽略
    }

本篇完结。
码字不易,宝贵经验分享不易,请各位支持原创,转载注明出处,多多关注作者。

相关推荐
打鱼又晒网1 分钟前
【MySQL】数据库精细化讲解:内置函数知识穿透与深度学习解析
数据库·mysql
大白要努力!7 分钟前
android 使用SQLiteOpenHelper 如何优化数据库的性能
android·数据库·oracle
运维-大白同学13 分钟前
将django+vue项目发布部署到服务器
服务器·vue.js·django
糖豆豆今天也要努力鸭20 分钟前
torch.__version__的torch版本和conda list的torch版本不一致
linux·pytorch·python·深度学习·conda·torch
烦躁的大鼻嘎29 分钟前
【Linux】深入理解GCC/G++编译流程及库文件管理
linux·运维·服务器
乐大师29 分钟前
Deepin登录后提示“解锁登陆密钥环里的密码不匹配”
运维·服务器
ac.char36 分钟前
在 Ubuntu 上安装 Yarn 环境
linux·运维·服务器·ubuntu
敲上瘾36 分钟前
操作系统的理解
linux·运维·服务器·c++·大模型·操作系统·aigc
tatasix1 小时前
MySQL UPDATE语句执行链路解析
数据库·mysql
长弓聊编程1 小时前
Linux系统使用valgrind分析C++程序内存资源使用情况
linux·c++