原文转载:Linux 信号(signal) - 简书 (jianshu.com)https://www.jianshu.com/p/f445bfeea40a
入门版:signal
原型
#include <signal.h>
typedef void (*sighandler_t)(int);
sighandler_t signal(int signum, sighandler_t handler);
kill
原型
#include <sys/types.h>
#include <signal.h>
int kill(pid_t pid, int sig);
例子:
signal_1.c
#include <signal.h>
#include <stdio.h>
// typedef void (*sighandler_t)(int);
// sighandler_t signal(int signum, sighandler_t handler);
void sighandle (int signum)
{
printf("get signum = %d\n",signum);
switch(signum){
case 2:
printf("SIGINT\n");
break;
case 9:
printf("SIGKILL\n");
break;
case 10:
printf("SIGUSR\n");
break;
}
printf("never quit\n");
}
int main()
{
//signal(SIGINT,sighandle);
signal(SIGINT,SIG_IGN);//忽略SIG
signal(SIGKILL,sighandle);
signal(SIGUSR1,sighandle);
while(1);
return 0;
}
signal_1kill.c
include <signal.h>
#include <stdio.h>
#include <sys/types.h>
#include <stdlib.h>
//int kill(pid_t pid, int sig);
int main(int argc,char **argv)
{
int signum;
int pid;
char cmd[128] = {0};
signum = atoi(argv[1]);
pid = atoi(argv[2]);
printf("num = %d pid = %d\n",signum,pid);
// kill(pid,signum);
sprintf(cmd,"kill -%d %d",signum,pid);
system(cmd);
printf("send signal ok\n");
return 0;
}
另附:
atoi
atoi (表示 ascii to integer)是把字符串转换成整型数的一个函数,应用在计算机程序和办公软件中。int atoi(const char *nptr) 函数会扫描参数 nptr字符串,会跳过前面的空白字符(例如空格,tab缩进)等。如果 nptr不能转换成 int 或者 nptr为空字符串,那么将返回 0 [1] 。特别注意,该函数要求被转换的字符串是按十进制数理解的。atoi输入的字符串对应数字存在大小限制(与int类型大小有关),若其过大可能报错-1
sprintf
sprintf指的是字符串格式化命令,函数声明为 int sprintf(char *string, char *format [,argument,...]);,主要功能是把格式化的数据写入某个字符串中,即发送格式化输出到 string 所指向的字符串。sprintf 是个变参函数。使用sprintf 对于写入buffer的字符数是没有限制的,这就存在了buffer溢出的可能性。解决这个问题,可以考虑使用 snprintf函数,该函数可对写入字符数做出限制。
高级版:sigaction
原型
int sigaction(int signum, const struct sigaction *act,struct sigaction *oldact);
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 {
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) */
}
sigaction_get,c
#include <stdio.h>
#include <signal.h>
#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 pid :%d\n",info->si_pid);
}
}
int main()
{
struct sigaction act;
printf("get pid =%d\n",getpid());
act.sa_sigaction = handler;
act.sa_flags = SA_SIGINFO;//be able to message
sigaction(SIGUSR1,&act,NULL);
while(1);
return 0;
}
sigqueue
原型
int sigqueue(pid_t pid, int sig, const union sigval value);
union sigval {
int sival_int;
void *sival_ptr;
};
sigqueue_send.c
#include <stdio.h>
#include <signal.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
int main(int argc,char **argv)
{
int signum;
int pid;
printf("pid = %d\n",getpid());
signum = atoi(argv[1]);
pid = atoi(argv[2]);
union sigval value;
value.sival_int = 100;
sigqueue(pid,signum,value);
printf("doen\n");
return 0;
}
运行效果