发送信号命令:
kill 信号的发送命令
kill -数字 +pid —>给某个进程发送对应的信号值
kill -l 查看系统中的信号值
man 7 signal —>查看信号的帮助文档
信号 值 动作 说明
──────────────────────────────────────────────────
SIGHUP 1 A 在控制终端上是挂起信号, 或者控制进程结束
SIGINT 2 A 从键盘输入的中断
SIGQUIT 3 C 从键盘输入的退出
SIGILL 4 C 无效硬件指令
SIGABRT 6 C 非正常终止, 可能来自 abort(3)
SIGFPE 8 C 浮点运算例外
SIGKILL 9 AEF 杀死进程信号
SIGSEGV 11 C 无效的内存引用
SIGPIPE 13 A 管道中止: 写入无人读取的管道
SIGALRM 14 A 来自 alarm(2) 的超时信号
SIGTERM 15 A 终止信号
SIGUSR1 30,10,16 A 用户定义的信号 1
SIGUSR2 31,12,17 A 用户定义的信号 2
SIGCHLD 20,17,18 B 子进程结束或停止
SIGCONT 19,18,25 继续停止的进程
SIGSTOP 17,19,23 DEF 停止进程
SIGTSTP 18,20,24 D 终端上发出的停止信号
SIGTTIN 21,21,26 D 后台进程试图从控制终端(tty)输入
SIGTTOU 22,22,27 D 后台进程试图在控制终端(tty)输出
以上的信号是常用信号
---------------------------------------------------------
SIGBUS 10,7,10 C 总线错误 (不正确的内存访问)
SIGPOLL A I/O就绪事件 (Sys V). 等同于SIGIO
SIGPROF 27,27,29 A 系统资源定时器(Profiling timer)超时
SIGSYS 12,-,12 C 用错误参数调用系统例程 (SVID)
SIGTRAP 5 C 跟踪/断点自陷
SIGURG 16,23,21 B 套接口上出现 urgent 情况 (4.2 BSD)
SIGVTALRM 26,26,28 A 虚拟超时时钟 (4.2 BSD)
SIGXCPU 24,24,30 C 超过了CPU时间限制 (4.2 BSD)
SIGXFSZ 25,25,31 C 超过了文件大小限制 (4.2 BSD)
-----------------------------------------------------------
SIGIOT 6 C IOT 自陷. 等同于 SIGABRT
SIGEMT 7,-,7
SIGSTKFLT -,16,- A 协处理器堆栈错误
SIGIO 23,29,22 A I/O 有效信号 (4.2 BSD)
SIGCLD -,-,18 等同于 SIGCHLD
SIGPWR 29,30,19 A 电源无效 (System V)
SIGINFO 29,-,- 等同于 SIGPWR
SIGLOST -,-,- A 文件锁丢失
SIGWINCH 28,28,20 B 窗口大小调整信号 (4.3 BSD, Sun)
SIGUNUSED -,31,- A 未使用的信号 (将成为 SIGSYS)
------------------------------------------------------------------
A 缺省动作是结束进程.
B 缺省动作是忽略这个信号.
C 缺省动作是结束进程, 并且核心转储.
D 缺省动作是停止进程.
E 信号不能被捕获.
F 信号不能被忽略.
------------------------------------------------------------------
如何捕抓linux系统中的信号:
#include <signal.h>
typedef void (*sighandler_t)(int);
sighandler_t signal(int signum, sighandler_t handler);
参数一:需要捕抓信号值
参数二:对应的处理函数
SIG_IGN ->忽略该信号
SIG_DFL ->执行默认动作
用户自定义动作void (*sighandler_t)(int) -> 函数指针,指向返回类型为 void 参数为int的函数 (处理函数)
//信号的发送
NAME
kill - send signal to a process
发送一个信号给进程
SYNOPSIS
#include <sys/types.h>
#include <signal.h>
int kill(pid_t pid, int sig);
参数一:需要发送的进程pid
参数二:需要发送的信号值
返回值:成功 0
失败 -1
//假设不想通过pid来发送信号,想通过进程名字来发送
system("killall -? 进程名");
system("killall -STOP mplayer")
system("killall -CONT mplayer")
给自己发送信号
#include <signal.h>
int raise(int sig); 等价于kill(getpid(), sig);
发送闹铃信号
#include <unistd.h>
unsigned int alarm(unsigned int seconds);
//参数一: seconds 在多少秒后触发一个闹钟信号
触发: SIGALRM 14 信号
//获取系统时间
#include <time.h>
time_t time(time_t *tloc);
//把获取后的时间转换成字符串格式
char *ctime(const time_t *timep);
//信号的屏蔽 :当解除屏蔽后,我们的信号还会再次触发。
当我们执行一些重要的初始化任务时,我们希望不被外界信号所干扰,所有我们需要把这些外来的信号给全部屏蔽掉。
信号屏蔽函数:
#include <signal.h>
int sigprocmask(int how, const sigset_t *set, sigset_t *oldset);
参数一:SIG_BLOCK 阻塞 (在原来的基础上再添加)
SIG_SETMASK 阻塞 (直接替换)
SIG_UNBLOCK 解除阻塞
参数二:信号操作集 新的
参数三:信号操作集 老的
返回值:成功: 0
失败: -1
信号操作集的添加与解除请看图…
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
//信号处理函数
void func(int arg)
{
printf("arg=%d\n",arg); //arg 当前触发的信号值
printf("你杀不死我!\n");
}
int main()
{
//忽略ctrl c
signal(SIGINT,func);
int i=0;
while(1)
{
printf("i=%d\n",i++);
if(i%3 == 0)
{
//发送一个信号出去
kill(getpid(),SIGINT);
}
else if(i>10)
break;
sleep(1);
}
return 0;
}
运行效果如下图:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <time.h>
//信号处理函数
void func(int arg)
{
printf("闹钟触发:%d\n",arg);
time_t timep;
//获取时间
time(&timep);
//转换时间
printf("%s",ctime(&timep));
alarm(1);//重新装置
}
int main()
{
//注册闹钟信号
signal(SIGALRM,func);
int i=0;
alarm(1); //1S发送一个闹钟信号
while(1);
return 0;
}
#include <stdio.h>
#include <signal.h>
#include <unistd.h>
//信号处理函数
void func(int arg)
{
printf("arg=%d\n",arg); //arg 当前触发的信号值
printf("你杀不死我!\n");
}
int main()
{
//注册信号处理函数
signal(SIGINT,func);
//屏蔽所有信号
//清空
sigset_t set;
sigemptyset(&set);
//添加所有信号操作集合
sigfillset(&set);
//开启信号的屏蔽
sigprocmask(SIG_BLOCK,&set,NULL);
//开始做重要的任务
int i=0;
while(1)
{
printf("i=%d\n",i++);
//解除屏蔽
if(i==10)
{
sigprocmask(SIG_UNBLOCK,&set,NULL);
break;
}
sleep(1);
}
printf("所有设备初始化完毕\n");
while(1);
}
运行效果如图: