信号
- linux定义了哪些信号,kill -l 查看当前系统定义的所有信号
- linux提供信号接口函数
- linux信号4种响应方式(进程终止)
查看信号功能:blog
给进程发送信号
命令
killall -信号名字/信号编号 进程名字
kill -信号名字/信号编号 进程PID
常用信号作用
2 SIGINT 终止信号(同ctrl+c)
9 杀死进程
19 SIGSTOP 停止一个作业控制进程
18 SIGCONT 继续停止的程序
发送信号函数
给进程发送linux下定义的信号
函数
#include <sys/types.h>
#include <signal.h>
int kill(pid_t pid, int sig);
int sigqueue(pid_t pid, int sig, const union sigval value);
union sigval {
int sival_int;
void *sival_ptr;
};
kill 参数:
pid --》 进程pid
sig -》 发送的信号,名字序号都可以
sigqueue 参数:
pid --》 进程pid
sig --》 发送的信号,名字序号都可以
value --》 发送信号另外携带的自定义数据,注意数据类型
给自己发送信号:
#include <signal.h>
int raise(int sig);
间隔时间给当前进程发送信号 SIGALRM
#include <unistd.h>
unsigned int alarm(unsigned int seconds);
替换信号的响应动作
比如:正常情况下INT信号 --》 停止
函数
#include <signal.h>
typedef void (*sighandler_t)(int);
sighandler_t signal(int signum, sighandler_t handler);
int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact);
struct sigaction {
void (*sa_handler)(int); //响应函数1,同signal设置的函数,只有信号序号传入,二选一
void (*sa_sigaction)(int, siginfo_t *, void *); //响应函数2,,二选一
sigset_t sa_mask; //先不管
int sa_flags; //标志位,设为0使用函数1,设为SA_SIGINFO使用函数2
void (*sa_restorer)(void);
};
signal 参数:signum --》 需要捕捉的信号
handler --》 信号替换的动作函数
SIG_IGN 忽略信号
SIG_DFL 默认动作
sigaction 参数:signum --》 需要捕捉的信号,除了SIGKILL 和 SIGSTOP
act --》 替换的动作
定义带参数的替换函数:void (*sa_sigaction)(int, siginfo_t *, void *);
参数: int --》 保存发送过来的信号序号
siginfo_t * --》 保存携带的数据指针,见上面的union sigval
void * --》 没有说明,用不到
oldact --》 备份act用的。一般不用设置成NULL。保存之前的act或当前的act,具体用man查看
使用
#include <signal.h>
#include<stdio.h>
void fun(int sig)
{
printf("我收到的信号是%d\n", sig);
printf("信号的默认动作已改变\n");
}
int main()
{
signal(SIGINT, fun);
while(1);
}
阻塞进程
阻塞程序,等待信号,收到信号才执行过去
#include <unistd.h>
int pause(void);
信号的屏蔽
忽略(见上):信号发过来就丢失了
屏蔽(也叫阻塞):把信号挡在进程外面,不响应,信号依然存在。解除后依旧可以继续响应之前发送过来的信号
函数
#include <signal.h>
/* Prototype for the glibc wrapper function */
int sigprocmask(int how, const sigset_t *set, sigset_t *oldset);
参数:
how --》SIG_BLOCK 设置信号阻塞,阻塞set和oldset
SIG_SETMASK 设置信号阻塞,只阻塞set
SIG_UNBLOCK 解除信号阻塞
set --》 保存想要阻塞的所用信号
sigset_t 是linux专门用来保存阻塞信号的阻塞掩码集
#include <signal.h>
int sigemptyset(sigset_t *set); //清空集合
int sigfillset(sigset_t *set); //把linux62个信号一起添加到里面
int sigaddset(sigset_t *set, int signum); //把signum添加进去
int sigdelset(sigset_t *set, int signum); //把signum从里面删除
int sigismember(const sigset_t *set, int signum); //判断signum在不在里面,在 1,不在 0
oldset --》 备份,一般是NULL
使用
#include <signal.h>
#include <stdio.h>
#include <unistd.h>
int main()
{
sigset_t myset;
sigaddset(&myset, SIGINT);
sigaddset(&myset, SIGQUIT);
sigprocmask(SIG_BLOCK, &myset, NULL);
pause();
}