Linux系统流程:管理和监控教程
任何操作系统的大脑都是其核心。但是只有操作系统(内核)的计算机是没有用的,因为没有人真正使用操作系统。计算机的最终用户总是关心程序,而不是操作系统。
操作系统真正要做的是提供一个环境,在那里这些程序可以运行。因此,操作系统的唯一任务就是为程序提供资源,使程序能够完成其任务。人们忘记了程序和操作系统之间的区别,仅仅是因为现代操作系统在操作系统本身的同时安装了大量的程序。
当你运行一个程序时,程序将启动一个或者多个进程,以完成它设计的任务。get启动的进程将自行执行和消亡,无需任何用户的干预。这个完美地处理进程的完整生命周期的奇妙任务是由内核本身完成的。对于Linux系统管理员来说,了解用于分析、监视和修改正在运行的进程的方法非常重要。在这篇文章中,我们将介绍Linux中进程的不同方面,以便更好地理解这个主题。
在Linux系统中运行任何命令都会导致一个进程被创建,而进程在完成创建它要做的工作之后就会死掉。让我们先弄清楚一些基本知识。正如我之前所说,每个程序都会创建一个或者多个进程。在任何时候,系统上都有多个进程在运行。
Linux操作系统中的每个进程都通过一个称为进程id的数字来标识。
Linux中进程id或者pid是什么?
进程ID只是一个唯一的标识号,它有助于标识Linux中的特定进程。PID是16位数字,依次分配给不同的进程。进程ID也称为线程组标识符(threadgroupidentifier,TGID)。如果我们想了解更多关于线程的细节,我建议我们阅读下面的文章。
导读:线程与Linux中的进程有何不同?
流程执行后,流程id号从流程表中释放,以供重用。
PID本身代表进程标识符。任何针对流程的修改都必须在流程标识符的帮助下完成。在没有字符的情况下,处理一个进程是不可能的,这是该进程所特有的。PID对于系统上运行的每个进程都是唯一的。进程id号从1开始(它总是为名为init的进程保留)
由于每个进程的进程号都是从Linux的进程号开始的,所以每个进程的进程号都是从初始化开始的。由于INIT是get启动的第一个进程,它也是Linux中所有其他进程的父进程。让我指出一些值得注意的事情,使概念更清晰。
Init是父进程和第一个进程,它总是获得进程ID号1.
Linux操作系统上可以运行的进程的最大数量是有限制的。这是从内核版本2.5开始引入的。
Linux系统的最大PID数可以从文件 /proc/sys/kernel/PID_max中找到。
[root@myvm1 ~]# cat /proc/sys/kernel/pid_max 32768 [root@myvm1 ~]#
上面的输出显示,进程id的最大数目是32768. 这意味着系统中一次可以同时运行32768个进程。
更高的PID值30000,在一个系统上并不意味着30000个进程在系统上运行。进程ID号1000并不总是意味着它在PID号30000之前启动。这是因为一旦一个进程释放了一个进程id号,它就会被重用。
如果我们有大量可用的内存,增加PID的总数是一个不错的方法,可以增加服务器可以处理的进程的数量。
下面的命令可以帮助你增加Linux进程的最大数量。
我们可以修改sysctl.conf系统文件来修改Linux中max-PID的这个限制。
4194303是64位Linux机器可以拥有的最大PID数。所以你可以修改你的 pid_max,比如4194303sysctl.conf系统Linux中的文件。
kernel.pid_max=<最大值>
如何列出运行在Linux机器上的进程?
在Linux系统中,有一个当前运行的不同的工具列表。其中一个常用的工具是 ps
让我们看看它的输出内容是什么,并了解每个字段。了解ps命令的各个领域,将使我们更深入地了解进程及其不同的参数。
[root@myvm1 ~]# ps aux USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND root 1 0.1 0.1 2064 624 ? Ss 08:16 0:00 init [3] root 2 0.0 0.0 0 0 ? S< 08:16 0:00 [migration/0] root 3 0.0 0.0 0 0 ? SN 08:16 0:00 [ksoftirqd/0] root 4 0.0 0.0 0 0 ? S< 08:16 0:00 [watchdog/0] root 5 0.0 0.0 0 0 ? S< 08:16 0:00 [events/0] root 6 0.0 0.0 0 0 ? S< 08:16 0:00 [khelper] root 7 0.0 0.0 0 0 ? S< 08:16 0:00 [kthread] root 10 0.0 0.0 0 0 ? S< 08:16 0:00 [kblockd/0] root 11 0.0 0.0 0 0 ? S< 08:16 0:00 [kacpid] root 175 0.0 0.0 0 0 ? S< 08:16 0:00 [cqueue/0] root 178 0.0 0.0 0 0 ? S< 08:16 0:00 [khubd] root 180 0.0 0.0 0 0 ? S< 08:16 0:00 [kseriod]
如果我们看到了 ps命令手册页,那么我在上面所示示例中使用的选项 aux被称为“ **使用BSD语法查看系统上的每个进程:”)
让我们理解输出的每一列。第一列是 USER列,它给出了启动进程的用户的名称。换句话说,它告诉我们进程的所有者。
PID(第二列)给出进程的PID号(我们已经在本文的上一节讨论过了)。如果我们注意到ps命令输出,INIT进程的进程ID号为1(这证明它是系统中启动的第一个进程)
%CPU(第三列)是进程当前正在使用的CPU数量的百分比。在危机期间,本专列可以非常有助于识别CPU密集型的进程。
%MEM(第四列)是进程使用的内存量的百分比。
VSZ和RSS告诉你进程使用的内存量。VSZ用于显示进程使用的虚拟内存量,但是RSS(驻留集大小)是进程正在使用的内存(物理内存)的一部分。
TTY显示进程开始的终端名称。无论何时执行命令,都可以启动进程。启动进程的终端将显示在ps output的TTY列下。
[root@myvm1 ~]# ps aux | grep ls root 13594 0.0 0.1 3912 672 pts/1 R+ 09:46 0:00 grep ls [root@myvm1 ~]# tty /dev/pts/1 [root@myvm1 ~]#
上面显示的例子,服务器有两个用途。首先,它显示,无论我们键入什么命令,它都将以该命令名启动进程。在上面的例子中,命令一运行,进程就以命令名 “grep ls”启动(在我们的例子中,这个过程非常短暂,因为输出已经显示,进程也退出了)
在输出中,tty列包含一个 pts/1,这是发出命令的tty名称,为了确认,我们还使用tty命令检查了tty名称。
但在某些情况下,会有一个问号(?)而不是该列中的tty名称。当进程不是从tty启动时,tty字段中出现问号。这意味着进程或者是守护进程,或者是系统启动的进程,或者是与cron作业相关的进程。
PS命令输出过程状态
根据当前状态,进程可以分为不同的状态。例如,进程可以是空闲的,等待用户输入,进程可以等待IO请求完成,进程可以是僵尸,甚至是孤立的。让我们来看看Linux中进程的不同状态。
让我们首先了解Linux中的不可中断和不间断进程。
当前没有执行任何任务,正在等待任何中断的进程,或者例如,正在等待来自用户的输入的进程通常处于可中断睡眠状态。进程的这种状态用 **“S”表示。你会发现系统中有大量进程处于 S状态。这是因为,大多数进程都处于已启动状态,并且正在等待根据需要执行某些操作。
等待完成某项任务的进程称为不可中断状态。例如,等待IO请求完成的进程进入不间断状态。这种状态在ps命令输出中用 D表示。我们不能向处于不间断状态的进程发送任何消息,因为它不接受任何信号或者消息。你通常不会看到,太多进程处于 D状态
相关内容:Linux下的IO监控
“进程状态”列还指示进程相对于其他进程的优先级。有两个符号表示进程的优先级
**“<”表示该进程比其他进程具有更高的优先级。换句话说,我们也可以说带有 <状态符号的进程表示在执行优先级方面它对其他进程不好。
另一方面, N,表示进程对其他进程是好的,这意味着状态为 N的进程比系统上运行的其他进程优先级低。
linux中的僵尸和孤立进程是什么?
另外两种被广泛讨论的身份被称为僵尸和孤儿。让我们逐一讨论僵尸和孤立进程。
在本文的开头,我们讨论了一个名为INIT的进程。INIT是Linux中所有其他进程的父进程。这是第一个在Linux系统上运行的进程。在Linux系统上运行的所有进程都有一个父进程。例如,打开一个shell,然后运行一个名为elinks的进程(它是一个基于文本的控制台浏览器)
在本例中,elinks进程是名为bash(启动它的shell)的父进程的子进程。类似地,如果我们在系统上运行httpd web服务器,那么所有其他httpd进程都将由一个主httpd进程生成(该进程由用户使用init脚本启动)。让我们在ps命令的帮助下查看已经在运行的Apache进程的父进程。
[root@myvm1 ~]# ps aux | grep 16975
汽车减少意味着
阿帕奇16975 0.0 0.7 23620 3812?S 13:47 0:00/usr/sbin/httpd
在上面的示例中,我们可以看到编号为16975的PID是一个Apache进程。让我们在ps命令的帮助下查看这个进程的父PID。
[root@myvm1 ~]# ps -p 16975 -o ppid= 16969
现在从上面的输出中我们知道16969是进程16975的父进程id。让我们看看这个父进程实际上是什么进程。
[root@myvm1 ~]# ps aux | grep 16969 root 16969 0.0 1.4 23620 7520 ? Ss 13:47 0:00 /usr/sbin/httpd
我们看到了吗,父进程是根用户启动的 /usr/sbin/httpd脚本。这样,每个进程都与其父进程有关系。归根结底,init是所有进程的父进程。
让我们回到僵尸和孤儿进程的讨论。僵尸过程具有真正僵尸的所有特征(没有灵魂的尸体称为僵尸)。僵尸进程被称为僵尸进程,因为它是一个死进程,没有任何任务要做(不利用任何系统资源),只是坐在进程表中由父进程获取。
当一个进程完成它的执行时,它通知它的父进程它已经完成了它的执行。现在,在得到通知后,父进程的任务是获取已完成执行的进程的完整状态,然后最终将其从进程表中删除,以便pid可供重用。有些不负责任的父进程需要花费大量时间来收集其子进程的完整状态,即使在得到通知之后也是如此。因为要将这些僵尸的父对象从列表中删除,所以才会将它们从僵尸列表中删除。
正如我所说,是不负责任的父母,他们对僵尸进程的存在负有责任。通常情况下,这是由于编程效率低下和错误造成的。但一般来说,僵尸不会造成任何伤害,因为它们是没有灵魂的尸体(它们不会消耗任何系统资源)。它们只是流程表中的一个条目,需要由父级删除)。但是,如果系统上有大量僵尸进程,那么你最终将运行我们的PID号。因为除非进程释放PID,否则它不能被重用,僵尸不会释放PID。僵尸进程用状态符号 Z表示,你不能杀死僵尸,因为它是一具尸体,你将如何杀死一具尸体。但可以肯定的是,我们可以要求父进程获取已完成执行的子进程。
这可以通过发送 SIGCHLD,信号来完成。这个信号会要求不负责任的父母去收割他们的孩子,他们是僵尸。假设2343是僵尸进程的父进程id(在Linux中,我们可以很容易地找到任何进程的父进程,通过本教程前面介绍的ps命令),我们可以向它发送sigchld信号,如下所示。
[root@myvm1 ~]# kill -s SIGCHLD 2343
现在让我们讨论Linux中的孤立进程是什么。孤儿过程是那些不幸的过程,其父母死后留下孩子。父母可能会死于意外事故(也就是说可能会撞车)。然而,一些强有力的程序会立即收养那些父母已不在家的孤儿。例如,INIT立即采用几乎所有的孤立进程。
在这种情况下,我们将看到PID no 1是它们的父进程。
在Unix和Linux系统中,每当我们杀死父进程时,所有子进程都会被销毁。这种情况通常会发生,直到或者除非一个进程被有意地设为孤立的,因此init将其作为子进程。当我们希望在很长一段时间内从shell运行程序时,这种有意使进程孤立的过程非常有用,而且它也不需要任何用户干预。通常,从命令行shell运行程序时,该程序将成为shell进程的子进程。所以当你从那个shell注销时,所有的孩子都会被杀。但在某些情况下,我们希望进程运行,直到它自己完成为止。
这可以通过有目的地使一个进程成为孤立进程来实现,以便INIT进程立即采用它。这是通过Linux中名为 nohup的命令来完成的
[root@myvm1 ~]# nohup sh sample.sh & [2] 22416 [root@myvm1 ~]# nohup: appending output to `nohup.out'
上面的命令启动示例.sh用nohup处理,这样即使在炮弹退出后也不会被杀死。最后的 &表示进程应该在后台运行(不用担心,我稍后会解释后台和前台进程)。
什么是linux的前台和后台进程?
以前,当我们在命令末尾使用 &运行示例脚本时,它会将该进程置于后台。现在让我们了解什么是背景和前景过程。
为了理解什么是背景和前景,让我们看一个例子。如果我们在linux终端上工作,那么在得到shell提示符之前,首先需要完成执行的每个命令。例如,如果我们想从终端运行一个类似于 yum update,的命令,我们需要先等待命令完成,然后才能在同一终端上运行另一个命令。
如果我们想同时一个接一个地运行多个命令,而不必等待每个命令完成,该怎么办。为此,我们需要在后台发送一个命令(进程),然后才能运行另一个命令。每当你运行一个命令,它默认运行在前台。但有一些方法可以用来将前台进程发送到后台。
[root@myvm1 ~]# yum update
当我们运行上述命令时,默认情况下它将运行前台,我们必须等到命令完成后,才能再次获得shell提示符以运行另一个命令。但是你可以暂停这个过程,或者说在 CTRL+Z的帮助下暂停这个过程。
[root@myvm1 ~]# yum update [1]+ Stopped yum update [root@myvm1 ~]#
我一按 CTRL+Z,进程就被暂停/停止。从上面的消息 [1]+stopped yum update中可以清楚地看到。]按[CTRL+Z]不是运行另一个命令或者返回shell提示符的好方法,因为它会暂停已经运行的进程。我们需要系统运行这个进程,并允许我们通过释放shell提示符运行另一个命令。
[[1]表示作业编号id。由于我们这里只有一个作业被挂起,因此给它的作业id编号为1. 现在让我们继续这个过程,把它放到前台。
[root@myvm1 ~]# fg %1 yum update
[1]如果我们需要继续运行另一个fg进程,我们仍需要等待它再次运行。这个问题的一个好的解决方案是将进程发送到后台,这样进程将继续运行,并且我们将返回shell提示符,以运行其他命令。
[root@myvm1 ~]# bg %1 [1]+ yum update &
上面的命令将恢复yum更新进程,并将该进程置于后台,以便我们可以运行其他命令。如果有多个进程在后台运行,那么可以在jobs命令的帮助下查看它们的状态,如下所示。
[root@myvm1 ~]# jobs [1]+ Running yum update & [root@myvm1 ~]#
我们可以在linux下的 fg and bg命令的帮助下随时在后台和前台之间切换,只需将确切的作业编号作为参数(%1、%2等)
或者,我们也可以在命令后立即使用 &,将其发送到后台。例如,让我们在运行时向后台发送相同的yum update命令。
[root@myvm1 ~]# yum update & [1] 31281
如我们所见,使用 &,符号也可以完成分配作业id号并将其发送到后台的相同操作。
一些过程监控命令
我们前面看到的PS命令在获取系统上运行的进程的完整细节方面做得很好。然而,linux中还有另一个工具,它可以监视所有进程的当前状态和活动状态。这个过程监控工具最有用的特性是能够与用户交互并根据需求对输出进行排序。
这正是top命令实用程序。
top - 05:23:08 up 7:09, 4 users, load average: 0.00, 0.11, 0.10 Tasks: 94 total, 1 running, 93 sleeping, 0 stopped, 0 zombie Cpu(s): 1.7%us, 0.7%sy, 0.0%ni, 97.0%id, 0.0%wa, 0.3%hi, 0.3%si, 0.0%st Mem: 515444k total, 441964k used, 73480k free, 73364k buffers Swap: 0k total, 0k used, 0k free, 276772k cached PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 31571 root 15 0 2196 1008 804 R 0.7 0.2 0:00.02 top 4535 root 15 0 1968 644 564 S 0.3 0.1 0:23.77 hald-addon-stor 1 root 15 0 2064 624 536 S 0.0 0.1 0:00.94 init 2 root RT -5 0 0 0 S 0.0 0.0 0:00.00 migration/0 3 root 34 19 0 0 0 S 0.0 0.0 0:00.00 ksoftirqd/0
top命令将继续更新其统计信息,默认情况下每3秒更新一次。但是,我们可以使用命令行选项更改此值
[root@myvm1 ~]# top -d 1
虽然top命令是一个非常好的工具,用于监视linux系统上的进程细节,但它也在一个界面中为我们提供了系统的完整概述。如果我们看到命令输出的顶部区域,我们将能够看到正在运行的系统的完整详细信息。
它向我们展示了以下内容。
没有用户登录
系统平均负载
正常运行时间
进程总数,以及休眠、运行、停止或者僵尸的进程数。
CPU统计,内存统计
我们可以根据内存使用情况、cpu使用情况、交换使用情况等,在命令中提供的排序选项的帮助下,对top命令的输出进行排序。我们可以按 SHIFT+O键获取选项,显示排序选项列表。
j: P = Last used cpu (SMP) * K: %CPU = CPU usage l: TIME = CPU Time m: TIME+ = CPU Time, hundredths n: %MEM = Memory usage (RES) o: VIRT = Virtual Image (kb) p: SWAP = Swapped size (kb) q: RES = Resident size (kb)
在可用的排序选项中,我们可以通过键入与所需排序相对应的字母进行排序,然后按 回车键。举例来说,如果你想对最上面的输出进行内存使用排序,那么你可以先进入这个排序菜单,按 SHIFT+O,然后按 n,再按 ENTER
让我们看看另一个有趣的命令,它将显示系统中所有进程的父子关系。
[root@myvm1 ~]# pstree init-+-acpid |-atd |-auditd-+-audispd---{audispd} | `-{auditd} |-automount---4*[{automount}] |-avahi-daemon---avahi-daemon |-crond |-cupsd |-dbus-daemon |-dhclient |-events/0 |-gam_server |-gpm |-hald---hald-runner-+-hald-addon-acpi | |-hald-addon-keyb | `-hald-addon-stor
很好,上面的pstree命令,显示了系统的完整进程树。从头到 tail。如果我们看到INIT位于顶部,它是所有进程的父进程。
大多数显示进程详细信息的命令行实用程序都是从 /proc,文件系统获取它们的信息。如果我们进入/proc文件系统,我们将能够看到单独进程的单独目录。
[root@myvm1 proc]# ll total 0 dr-xr-xr-x 5 root root 0 Jan 11 07:59 1 dr-xr-xr-x 5 root root 0 Jan 11 07:59 10 dr-xr-xr-x 5 root root 0 Jan 11 07:59 11 dr-xr-xr-x 5 root root 0 Jan 12 06:10 1443 dr-xr-xr-x 5 root root 0 Jan 12 06:10 1446 dr-xr-xr-x 5 root root 0 Jan 11 07:59 1684 dr-xr-xr-x 5 apache apache 0 Jan 11 13:47 16971 dr-xr-xr-x 5 apache apache 0 Jan 11 13:47 16972 dr-xr-xr-x 5 apache apache 0 Jan 11 13:47 16973
这些单独的PID目录包含完整的进程信息。让我们看看 /proc.下的一个PID目录的内容,让我们进入一个名为4282的PID目录来查看它的内容。
[root@myvm1 4282]# ls attr cpuset fd mem oom_score stat wchan auxv cwd limits mounts root statm cmdline environ loginuid mountstats schedstat status coredump_filter exe maps oom_adj smaps task
虽然我无法解释其中的每个文件和目录内容,但让我们了解其中的一些内容。
命令行文件说明运行此进程时使用的命令行参数。
例如,pid 4282是一个mysql进程,让我们看看cmdline文件的内容。
[root@myvm1 4282]# cat cmdline /usr/libexec/mysqld--basedir=/usr--datadir=/var/lib/mysql--user=mysql--federated--log-error=/var/log/mysqld.log--pid-file=/var/run/mysqld/mysqld.pid--socket=/var/lib/mysql/mysql.sock
CWD将流程链接到流程的工作目录
exe是进程的可执行文件。
environ文件包含进程的环境变量。
[root@myvm1 4282]# cat environ CONSOLE=/dev/consoleSELINUX_INIT=YESTERM=linuxINIT_VERSION=sysvinit-2.86PATH=/sbin:/usr/sbin:/bin:/usr/binrunlevel=3RUNLEVEL=3PWD=/LANG=en_US.UTF-8previous=NPREVLEVEL=NSHLVL=3HOME=/MYSQL_HOME=/usr_=/usr/bin/nohup
包含有关进程的完整信息的文件是 状态文件,让我们看看该文件的内容。
[root@myvm1 4282]# cat status Name: mysqld State: S (sleeping) SleepAVG: 96% Tgid: 4282 Pid: 4282 PPid: 4169 TracerPid: 0 Uid: 27 27 27 27 Gid: 27 27 27 27 FDSize: 256 Groups: 27 VmPeak: 149852 kB VmSize: 132704 kB VmLck: 0 kB VmHWM: 22248 kB VmRSS: 22060 kB VmData: 118972 kB VmStk: 84 kB VmExe: 6764 kB VmLib: 5580 kB VmPTE: 104 kB StaBrk: 092ce000 kB Brk: 09719000 kB StaStk: bfa2fcd0 kB ExecLim: 086e3000 Threads: 10 SigQ: 0/8192 SigPnd: 0000000000000000 ShdPnd: 0000000000000000 SigBlk: 0000000000087007 SigIgn: 0000000000001006 SigCgt: 00000001800066e9 CapInh: 0000000000000000 CapPrm: 0000000000000000 CapEff: 0000000000000000 Cpus_allowed: 00000001 Mems_allowed: 1
是的,那个文件包含了整个过程的细节。大多数系统监视工具,只从这个位置获取进程信息。让我们看看这个文件提供了什么信息。
工艺名称
PID
父进程ID,指示bu PPID
进程的uid和gid
过程的状态
虚拟内存和实内存统计等。
在Linux下发送信号进行处理
大多数在日常生活中使用Linux的人都知道一个名为 kill的命令,虽然这个命令通常用于杀死进程,但是使用 kill也可以实现其他功能
kill命令完成的一个主要任务是向正在运行的进程发送信号。有各种类型的信号可以发送到进程。进程对特定信号的响应方式取决于该进程是如何编程的。我们来讨论一些常用的杀戮信号。
我们已经讨论过,当你退出终端时,从终端运行的程序将退出。基本上,当你退出终端时,程序从终端运行时会收到一个 SIGHUP信号。
信号显示挂断的过程。基本上这个信号会终止这个过程。
当你输入 CTRL+C或者 CTRL+Z到一个正在运行的进程时会发生什么情况。 CTRL+C向正在运行的进程发送一个 SIGINT,信号(大多数情况下,它会终止正在运行的应用程序)
我们之前已经看到,一个正在运行的程序可以使用 CTRL+Z来暂停。当我们按下CTRL+Z时,shell将向正在运行的程序发送一个 SIGSTOP信号。
Kill命令与不同的信号级别一起用作参数。让我们看看Linux中KILL命令的一些示例。
例1
上述命令将向正在运行的进程发送一个 SIGHUP信号。这完全取决于程序在接收SIGHUP信号时的配置。例如,如果我们使用 kill-1向Apache进程发送SIGHUP信号,Apache将重新读取其配置文件。如果我们想确认这一点,我们可以随时打开 /etc/init.d/httpd脚本并搜索“ reload”。
例2
上面显示的命令将向正在运行的进程发送一个 SIGINT信号。这与按CTRl+C非常相同
例3
上面显示的信号将向正在运行的进程发送一个 SIGKILL,信号。此信号要求进程立即退出。这是一种扼杀进程的苛刻方法。但这个过程永远不会忽视这个信号。
这个信号的一个主要缺点是,这个过程会被不恰当地杀死。
例4
这是最有文化的杀戮信号。此命令将向正在运行的进程发送SIGTERM信号。这将要求进程优雅地终止自己。对于Linux中的任何进程,这是最好的方法。
SIGTERM是一种安全的信号,不会对过程造成危害。
解释Linux中所有可用的signal形式超出了本文的范围。我们可以通过运行下面的命令获得KILL命令支持的信号的完整列表。
[root@myvm1 ~]# kill -l 1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL 5) SIGTRAP 6) SIGABRT 7) SIGBUS 8) SIGFPE 9) SIGKILL 10) SIGUSR1 11) SIGSEGV 12) SIGUSR2 13) SIGPIPE 14) SIGALRM 15) SIGTERM 16) SIGSTKFLT 17) SIGCHLD 18) SIGCONT 19) SIGSTOP 20) SIGTSTP 21) SIGTTIN 22) SIGTTOU 23) SIGURG 24) SIGXCPU 25) SIGXFSZ 26) SIGVTALRM 27) SIGPROF 28) SIGWINCH 29) SIGIO 30) SIGPWR 31) SIGSYS 34) SIGRTMIN 35) SIGRTMIN+1 36) SIGRTMIN+2 37) SIGRTMIN+3 38) SIGRTMIN+4 39) SIGRTMIN+5 40) SIGRTMIN+6 41) SIGRTMIN+7 42) SIGRTMIN+8 43) SIGRTMIN+9 44) SIGRTMIN+10 45) SIGRTMIN+11 46) SIGRTMIN+12 47) SIGRTMIN+13 48) SIGRTMIN+14 49) SIGRTMIN+15 50) SIGRTMAX-14 51) SIGRTMAX-13 52) SIGRTMAX-12 53) SIGRTMAX-11 54) SIGRTMAX-10 55) SIGRTMAX-9 56) SIGRTMAX-8 57) SIGRTMAX-7 58) SIGRTMAX-6 59) SIGRTMAX-5 60) SIGRTMAX-4 61) SIGRTMAX-3 62) SIGRTMAX-2 63) SIGRTMAX-1 64) SIGRTMAX