linux信号表
A. linux进程详解
ps是Linux 中最基础的浏览系统中的进程的命令。能列出系统中运行的进程,包括进程号、命令、CPU使用量、内存使用量等。接下来解读一下Linux操作系统的进程和Windows“Ctrl+Alt+delete”直接的差异。
在进行了解进程命令之前需要知道进程的一些状态
ps工具标识进程的5种状态码:
Linux操作系统进程执行的状态转换图如图所示:
下面来看一下 ps命令
ps --help命令可以查看ps命令的使用说明
或者使用 man ps命令 查询ps的详细说明
在 man手册 关于ps的解读中,总结了一下几个参数的含义:
以上的参数是可以拼接使用的,那就了解一些常用的参数组合
ps aux命令
ps -ef命令
查看进程状态这两个是命令是最常用的,使用 ps aux 可以查看进程的详细运行状态等。使用 ps -ef 不仅可以显示自身的PID,也可以显示PPID(父进程)。但是显示不了进程的运行状态
top命令
top命令是Linux下常用的性能分析工具,能够实时显示系统中各个进程的资源占用状况,类似于Windows的任务管理器
man手册关于top的解释
关闭进程,重启进程
在上一片文章中 linux的目录结构 里面说过,在目录/etc/init.d/目录下包含许多系统各种服务的启动和停止脚本。假设进程占用内存较大或者进程异常,我们是重启这个进程restart。如下图所示:
我们重启了mysqld这个进程,可以看出进程号已经改变(从15743到15964),说明进程已经重启。
Linux下有3个特殊的进程,idle进程(PID=0), init进程(PID=1)和kthreadd(PID=2)
我们来看一下进程状态[下面是删减版,进程数量太多,列举一部分]
可以看到很多进程的PPID号是1和2。也就是init进程和kthreadd进程。
在使用Windows系统的过程中,都碰到过应用程序卡死的情况。应对此问题,我们一般都是等待失去响应的程序恢复,或者是直接使用任务管理器将其强制关闭,然后再重新打开。
在Linux中,遇到特别耗费资源的进程,当然需要使用 top命令 查看进程占用率高的进程。或者使用 free -m命令 查看内存剩余。假设需要强杀进程来释放空间。我们涉及到Linux中信号📶的知识,在这里简单的描述一下,信号的详解会在接下来的文章里面叙述。
free -m命令查看内存空间
在linux中存在着64种信号
使用 kill -l命令 查看信号列表
在前面说过进程会被这些个信号> (进程收到SIGSTOP, SIGSTP, SIGTIN, SIGTOU信号强制停止运行) 那问题就在于如何发信号给这些个进程。
使用kill命令发信号
我们从上面可以看到 mysqld进程被重启了 。
关于Linux的这一块进程的知识还有很多,后面的文章跟大家分享僵尸进程,孤儿进程等等知识,以及守护进程(daemon进程).
B. linux signal 11 是什么意思
通过kill -l 可以查看信号列表,11 是段错误
$ 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 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
C. linux有哪些信号不会被阻塞
1. 信号在内核中的表示
我们知道了信号产生的各种原因,而实际执行信号处理的动作,叫做信号递达(Delivery)。信号从产生到递达之间的状态,称为信号未决(Pending)。进程可以选择阻塞(Block)某个信号。被阻塞的信号产生时将保持在未决状态,直到进程解除对此信号的阻塞,才执行递达的动作。
注意,阻塞和忽略是不同的,只要信号被阻塞就不会递达,而忽略是在递达之后可选的一种处理动作。
每个信号都有两个标志位分别表示阻塞和未决,,还有一个函数指针表示处理动作,信号产生时,内核在进程控制块中设置该信号的未决标志,直到信号递达才清除该标志。
SIGHUP信号未阻塞也未产生过,当它递达时执行默认处理动作。
SIGINT信号产生过,但正在被阻塞,所以暂时不能递达。虽然它的处理动作是忽略,但在没有解除阻塞之前不能忽略这个信号,因为进程仍有机会改变处理动作之后再解除阻塞。
SIGQUIT信号未产生过,一旦产生SIGQUIT信号将被阻塞,它的处理动作是用户自定义函数sighandler。
如果在进程解除对某信号的阻塞之前这种信号产生过多次,将如何处理?
POSIX.1允许系统递送该信号一次或多次。Linux是这样实现的:常规信号在递达之前产生多次只计一次,而实时信号在递达之前产生多次可以依次放在一个队列里。
从上图来看,每个信号只有一个bit的未决标志,非0即1,不记录该信号产生了多少次,阻塞标志也是这样表示的。因此,未决和阻塞标志可以用相同的数据类型sigset_t来存储,sigset_t称为信号集,这个类型可以表示每个信号的“有效”或“无效”状态,在阻塞信号集中“有效”和“无效”的含义是该信号是否被阻塞,而在未决信
号集中“有效”和“无效”的含义是该信号是否处于未决状态。
2. 信号集操作函数
sigset_t类型对于每种信号用一个bit表示“有效”或“无效”状态,至于这个类型内部如何存储这些bit则依赖于系统实现,从使用者的角度是不必关心的,使用者只能调用以下函数来操作sigset_t变量,而不应该对它的内部数据做任何解释,比如用printf直接打印sigset_t变量是没有意义的。
#include <signal.h>
int sigemptyset(sigset_t *set); ----- 初始化set指向的信号集,使其中所有信号的对应bit清零,表示该信号集不包含任何有效信号.
int sigfillset(sigset_t *set); ---- 初始化set所指向的信号集,使其中所有信号的对应bit置位,表示该信号集的有效信号包括系统支持的所有信号。
int sigaddset(sigset_t *set, int signo);
int sigdelset(sigset_t *set, int signo);
int sigismember(const sigset_t *set, int signo);
注意,在使用sigset_t类型的变量之前,一定要调用sigemptyset或sigfillset做初始化,使信号集处于确定的状态。
3. sigprocmask
调用函数sigprocmask可以读取或更改进程的信号屏蔽字。
如果oset是非空指针,则读取进程的当前信号屏蔽字通过oset参数传出。如果set是非空指针,则更改进程的信号屏蔽字,参数how指示如何更改。如果oset和set都是非空指针,则先将原来的信号屏蔽字备份到oset里,然后根据set和how参数更改信号屏蔽字。假设当前的信号屏蔽字为mask,下表说明了how参数的可选值。
D. linux 关闭时会给程序法什么信号
运行如下命令,可看到Linux支持的信号列表:
# 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
列表中,编号为1 ~ 31的信号为传统UNIX支持的信号,是不可靠信号(非实时的),编号为32 ~ 63的信号是后来扩充的,称做可靠信号(实时信号)。不可靠信号和可靠信号的区别在于前者不支持排队,可能会造成信号丢失,而后者不会。
编号小于SIGRTMIN的信号解释如下:
1) SIGHUP
本信号在用户终端连接(正常或非正常)结束时发出, 通常是在终端的控制进程结束时, 通知同一session内的各个作业, 这时它们与控制终端不再关联。
登录Linux时,系统会分配给登录用户一个终端(Session)。在这个终端运行的所有程序,包括前台进程组和 后台进程组,一般都属于这个 Session。当用户退出Linux登录时,前台进程组和后台有对终端输出的进程将会收到SIGHUP信号。这个信号的默认操作为终止进程,因此前台进 程组和后台有终端输出的进程就会中止。不过可以捕获这个信号,比如wget能捕获SIGHUP信号,并忽略它,这样就算退出了Linux登录,wget也 能继续下载。
此外,对于与终端脱离关系的守护进程,这个信号用于通知它重新读取配置文件。
2) SIGINT
程序终止(interrupt)信号, 在用户键入INTR字符(通常是Ctrl-C)时发出,用于通知前台进程组终止进程。
E. linux下的Ctrl+C信号值是多少,该如何解决
Ctrl+C:送SIGINT信号,默认进程会结束,但是进程自己可以重定义收到这个信号的行为。 Ctrl+Z:送SIGSTOP信号,进程只是被停止,再送SIGCONT信号,进程继续运行。 ctrl-d 不是发送信号,而是表示一个特殊的二进制值,表示 EOF 有些信号不能被屏蔽,比如中断,还应该有杀死进程的信号,要不然内核怎么做操作系统中的老大。实际上,SIGKILL和SIGSTOP信号是不能被屏蔽或阻止的,他们的默认动作总是会被执行的。
F. linux信号量的问题
sem_init:初始化信号量sem_t,初始化的时候可以指定信号量的初始值,以及是否可以在多进程间共享。
sem_wait:一直阻塞等待直到信号量>0。
sem_timedwait:阻塞等待若干时间直到信号量>0。
sem_post:使信号量加1。
sem_destroy:释放信号量。和sem_init对应。 答案补充 关于各函数的具体参数请用man查看,如man sem_init可查看该函数的帮助
G. linux 如何查看进程信号状态
这个在设置里面你直接就可以找到,然后查看到他的状态
H. linux 在哪个文件下查看信号列表
通过命令+文件名查看内容。如下命令可以查看。 1, cat :由第一行开始显示文件内容; 2,tac:从最后一行开始显示,可以看出tac与cat字母顺序相反; 3,nl:显示的时候输出行号; 4,more:一页一页的显示文件内容;
I. Linux进程间通信
linux下进程间通信的几种主要手段简介:
一般文件的I/O函数都可以用于管道,如close、read、write等等。
实例1:用于shell
管道可用于输入输出重定向,它将一个命令的输出直接定向到另一个命令的输入。比如,当在某个shell程序(Bourne shell或C shell等)键入who│wc -l后,相应shell程序将创建who以及wc两个进程和这两个进程间的管道。
实例二:用于具有亲缘关系的进程间通信
管道的主要局限性正体现在它的特点上:
有名管道的创建
小结:
管道常用于两个方面:(1)在shell中时常会用到管道(作为输入输入的重定向),在这种应用方式下,管道的创建对于用户来说是透明的;(2)用于具有亲缘关系的进程间通信,用户自己创建管道,并完成读写操作。
FIFO可以说是管道的推广,克服了管道无名字的限制,使得无亲缘关系的进程同样可以采用先进先出的通信机制进行通信。
管道和FIFO的数据是字节流,应用程序之间必须事先确定特定的传输"协议",采用传播具有特定意义的消息。
要灵活应用管道及FIFO,理解它们的读写规则是关键。
信号生命周期
信号是进程间通信机制中唯一的异步通信机制,可以看作是异步通知,通知接收信号的进程有哪些事情发生了。信号机制经过POSIX实时扩展后,功能更加强大,除了基本通知功能外,还可以传递附加信息。
可以从两个不同的分类角度对信号进行分类:(1)可靠性方面:可靠信号与不可靠信号;(2)与时间的关系上:实时信号与非实时信号。
(1) 可靠信号与不可靠信号
不可靠信号 :Linux下的不可靠信号问题主要指的是信号可能丢失。
可靠信号 :信号值位于SIGRTMIN和SIGRTMAX之间的信号都是可靠信号,可靠信号克服了信号可能丢失的问题。Linux在支持新版本的信号安装函数sigation()以及信号发送函数sigqueue()的同时,仍然支持早期的signal()信号安装函数,支持信号发送函数kill()。
对于目前linux的两个信号安装函数:signal()及sigaction()来说,它们都不能把SIGRTMIN以前的信号变成可靠信号(都不支持排队,仍有可能丢失,仍然是不可靠信号),而且对SIGRTMIN以后的信号都支持排队。这两个函数的最大区别在于,经过sigaction安装的信号都能传递信息给信号处理函数(对所有信号这一点都成立),而经过signal安装的信号却不能向信号处理函数传递信息。对于信号发送函数来说也是一样的。
(2) 实时信号与非实时信号
前32种信号已经有了预定义值,每个信号有了确定的用途及含义,并且每种信号都有各自的缺省动作。如按键盘的CTRL ^C时,会产生SIGINT信号,对该信号的默认反应就是进程终止。后32个信号表示实时信号,等同于前面阐述的可靠信号。这保证了发送的多个实时信号都被接收。实时信号是POSIX标准的一部分,可用于应用进程。非实时信号都不支持排队,都是不可靠信号;实时信号都支持排队,都是可靠信号。
发送信号的主要函数有:kill()、raise()、 sigqueue()、alarm()、setitimer()以及abort()。
调用成功返回 0;否则,返回 -1。
sigqueue()是比较新的发送信号系统调用,主要是针对实时信号提出的(当然也支持前32种),支持信号带有参数,与函数sigaction()配合使用。
sigqueue的第一个参数是指定接收信号的进程ID,第二个参数确定即将发送的信号,第三个参数是一个联合数据结构union sigval,指定了信号传递的参数,即通常所说的4字节值。
sigqueue()比kill()传递了更多的附加信息,但sigqueue()只能向一个进程发送信号。sigqueue()比kill()传递了更多的附加信息,但sigqueue()只能向一个进程发送信号。
inux主要有两个函数实现信号的安装: signal() 、 sigaction() 。其中signal()在可靠信号系统调用的基础上实现, 是库函数。它只有两个参数,不支持信号传递信息,主要是用于前32种非实时信号的安装;而sigaction()是较新的函数(由两个系统调用实现:sys_signal以及sys_rt_sigaction),有三个参数,支持信号传递信息,主要用来与 sigqueue() 系统调用配合使用,当然,sigaction()同样支持非实时信号的安装。sigaction()优于signal()主要体现在支持信号带有参数。
消息队列就是一个消息的链表。可以把消息看作一个记录,具有特定的格式以及特定的优先级。对消息队列有写权限的进程可以向中按照一定的规则添加新消息;对消息队列有读权限的进程则可以从消息队列中读走消息。消息队列是随内核持续的
消息队列的内核持续性要求每个消息队列都在系统范围内对应唯一的键值,所以,要获得一个消息队列的描述字,只需提供该消息队列的键值即可;
消息队列与管道以及有名管道相比,具有更大的灵活性,首先,它提供有格式字节流,有利于减少开发人员的工作量;其次,消息具有类型,在实际应用中,可作为优先级使用。这两点是管道以及有名管道所不能比的。同样,消息队列可以在几个进程间复用,而不管这几个进程是否具有亲缘关系,这一点与有名管道很相似;但消息队列是随内核持续的,与有名管道(随进程持续)相比,生命力更强,应用空间更大。
信号灯与其他进程间通信方式不大相同,它主要提供对进程间共享资源访问控制机制。相当于内存中的标志,进程可以根据它判定是否能够访问某些共享资源,同时,进程也可以修改该标志。除了用于访问控制外,还可用于进程同步。信号灯有以下两种类型:
int semop(int semid, struct sembuf *sops, unsigned nsops); semid是信号灯集ID,sops指向数组的每一个sembuf结构都刻画一个在特定信号灯上的操作。
int semctl(int semid,int semnum,int cmd,union semun arg)
该系统调用实现对信号灯的各种控制操作,参数semid指定信号灯集,参数cmd指定具体的操作类型;参数semnum指定对哪个信号灯操作,只对几个特殊的cmd操作有意义;arg用于设置或返回信号灯信息。
进程间需要共享的数据被放在一个叫做IPC共享内存区域的地方,所有需要访问该共享区域的进程都要把该共享区域映射到本进程的地址空间中去。系统V共享内存通过shmget获得或创建一个IPC共享内存区域,并返回相应的标识符。内核在保证shmget获得或创建一个共享内存区,初始化该共享内存区相应的shmid_kernel结构注同时,还将在特殊文件系统shm中,创建并打开一个同名文件,并在内存中建立起该文件的相应dentry及inode结构,新打开的文件不属于任何一个进程(任何进程都可以访问该共享内存区)。所有这一切都是系统调用shmget完成的。
shmget()用来获得共享内存区域的ID,如果不存在指定的共享区域就创建相应的区域。shmat()把共享内存区域映射到调用进程的地址空间中去,这样,进程就可以方便地对共享区域进行访问操作。shmdt()调用用来解除进程对共享内存区域的映射。shmctl实现对共享内存区域的控制操作。这里我们不对这些系统调用作具体的介绍,读者可参考相应的手册页面,后面的范例中将给出它们的调用方法。
注:shmget的内部实现包含了许多重要的系统V共享内存机制;shmat在把共享内存区域映射到进程空间时,并不真正改变进程的页表。当进程第一次访问内存映射区域访问时,会因为没有物理页表的分配而导致一个缺页异常,然后内核再根据相应的存储管理机制为共享内存映射区域分配相应的页表。
J. Linux中同步信号和异步信号分别怎么解释
Linux异步信号
1.int pthread_kill(pthread_t threadid, intsigno);
向特定的线程发送信号signo
2.int pthread_sigmask(int how, const sigset_t*newmask, sigset_t *oldmask);
设置线程的信号屏蔽码
3.int sigwait(const sigset_t *set, int *sig);
阻塞线程,等待set中指定的信号之一到达,并将到达的信号存入*sig。
4.代码
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <signal.h>
//#define SIGUSRR 40;
int SIGUSRR = 40;
void* threadOne(void *arg)
{
sigset_tsigset;
intsigno;
sigemptyset(&sigset);
sigaddset(&sigset,SIGUSRR);
pthread_sigmask(SIG_BLOCK,&sigset, NULL);
while(1)
{
sigwait(&sigset,&signo);
printf("getthread cond sig!\n");
}
}
int main(int argc, char **argv)
{
if(argc != 1)
{
printf("Usage:\n");
printf("threadcond\n");
return1;
}
pthread_tthreadId;
if(pthread_create(&threadId,NULL, threadOne, NULL) != 0)
{
printf("threadcreate error! \n");
return1;
}
//structsigaction act;
//act.sa_handler=SIG_IGN;
//sigemptyset(&act.sa_mask);
//act.sa_flags=0;
//sigaction(SIGUSRR,&act,0);//设置信号SIGUSR1的处理方式忽略
usleep(1000000);
pthread_kill(threadId,SIGUSRR);
usleep(1000000);
pthread_kill(threadId,SIGUSRR);
usleep(2000000);
return0;
}