信号
程序在运行时,系统所传来的指示。(你在家呆着有人来敲门)
Linux下常见信号
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
通过kill -l 可查看所有的信号
signal
捕捉信号并作出指定反应
1.原函数
#include <signal.h>
typedef void (*sighandler_t)(int);
sighandler_t signal(int signum, sighandler_t handler);
- int signum —— 收到的指令
- sighandler_t handler —— 执行的命令
- 示例
使用ctrl+c无法使程序终止
#include <signal.h>
#include <stdio.h>
void handler(int signum)
{
printf("get signum: %d\n",signum);
printf("never quit\n");
}
int main()
{
signal(SIGINT,handler);
while(1);
return 0;
}
使用ctrl+z退出程序或使用ps -aux|grep 执行文件名,查找进程号后使用kill -9 进程号 终止
sigaction
接收信号函数
-
原函数
#include <signal.h> int sigaction(int signum, const struct sigaction *act,struct sigaction *oldact);
- int signum —— 捕捉到的信号
- const struct sigaction *act —— 定义好的结构体存储各种处理信息
- struct sigaction *oldact —— 之前处理过的信息
其中const struct sigaction默认如下
struct sigaction {
void (*sa_handler)(int);
void (*sa_sigaction)(int, siginfo_t *, void *);
sigset_t sa_mask;
int sa_flags;
void (*sa_restorer)(void);
};
在这其中siginfo_t 结构体默认如下
siginfo_t {
int si_signo; /* Signal number */
int si_errno; /* An errno value */
int si_code; /* Signal code */
int si_trapno; /* Trap number that caused
hardware-generated signal
(unused on most architectures) */
pid_t si_pid; /* Sending process ID */
uid_t si_uid; /* Real user ID of sending process */
int si_status; /* Exit value or signal */
clock_t si_utime; /* User time consumed */
clock_t si_stime; /* System time consumed */
sigval_t si_value; /* Signal value */
int si_int; /* POSIX.1b signal */
void *si_ptr; /* POSIX.1b signal */
int si_overrun; /* Timer overrun count;
POSIX.1b timers */
int si_timerid; /* Timer ID; POSIX.1b timers */
void *si_addr; /* Memory location which caused fault */
long si_band; /* Band event (was int in
glibc 2.3.2 and earlier) */
int si_fd; /* File descriptor */
short si_addr_lsb; /* Least significant bit of address
(since Linux 2.6.32) */
void *si_lower; /* Lower bound when address violation
occurred (since Linux 3.19) */
void *si_upper; /* Upper bound when address violation
occurred (since Linux 3.19) */
int si_pkey; /* Protection key on PTE that caused
fault (since Linux 4.6) */
void *si_call_addr; /* Address of system call instruction
(since Linux 3.5) */
int si_syscall; /* Number of attempted system call
(since Linux 3.5) */
unsigned int si_arch; /* Architecture of attempted system call
(since Linux 3.5) */
}
其中handler初始参量如下
void
handler(int sig, siginfo_t *info, void *ucontext)
{
…
}
- 示例见最后
sigqueue
发送信号函数
-
原函数
#include <signal.h> int sigqueue(pid_t pid, int sig, const union sigval value);
- pid_t pid —— 传递信号的程序进程号
- int sig —— 传递的信号
- const union sigval value —— 传递的值
其中const union sigval结构体默认如下
union sigval {
int sival_int;
void *sival_ptr;
};
- 示例见最后
信号的通信示例
write.c
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
int main(int argc,char **argv)
{
int signum;
int pid;
signum = atoi(argv[1]); //将进程号,信号转化为int型
pid = atoi(argv[2]);
union sigval value; //赋值
value.sival_int = 100;
sigqueue(pid,signum,value); //传递信号
printf("%d,done\n",getpid());
return 0;
}
read.c
#include <sys/types.h>
#include <unistd.h>
void handler(int signum,siginfo_t *info,void *context)
{
printf("get signum %d\n",signum);
if(context != NULL){
printf("get data %d\n",info->si_int);
printf("get data %d\n",info->si_value.sival_int);
printf("from:%d\n",info->si_pid);
}
}
int main()
{
struct sigaction act;
printf("pid = %d\n",getpid());
act.sa_sigaction = handler; //将执行的指令导入
act.sa_flags = SA_SIGINFO; //使其接受3个参数
sigaction(SIGUSR1,&act,NULL); //获取到信号后执行指令
while(1);
return 0;
}
运行效果
运行write.c后等待接受信号,read.c将信号和值传递过来后打出传递过来的值