正点原子 Linux C ——信号的产生和处理

发布时间 2023-08-09 10:35:46作者: FBshark

信号的产生:

方式1: Shell 命令

kill 命令,Ctrl+C 或者 Ctrl+\ 

方式2:使用系统调用 kill()

#include <sys/types.h> 
#include <signal.h> 
/**
@pid:要发送的进程号
@signum:参数signum指定需要发送的信号编号,也可设置为0,如果参数sig设置为0则表示不发送信号,但任执行错误检查,这通常可用于检查参数pid指定的进程是否存在。
*/
int kill(pid_t pid, int signum);

 方式3: 使用系统调用 raise()

#include <signal.h> 
//向自身进程发送信号,等价于 kill(getpid(), sig);
int raise(int sig);

方式4:使用alarm()函数

可以设置一个定时器(闹钟),当定时器定时时间到时,内核会向进程发送SIGALRM信号 (注意:非循环触发)

#include <unistd.h> 
//相当于 kill(getpid(), SIGALRM)
unsigned int alarm(unsigned int seconds);

方式5:使用pause()函数

pause()系统调用可以使得进程暂停运行、进入休眠状态,直到进程捕获到一个信号为止,只有执行了信号处理函数并从其返回时,pause()才返回。

#include <unistd.h> 
int pause(void);

方式6:发送队列管理的实时信号(可靠信号)

#include <signal.h>
int sigqueue(pid_t pid, int sig, const union sigval value);

//携带的伴随数据
typedef union sigval { 
    int sival_int; 
    void *sival_ptr; } 
sigval_t;

 

信号的处理:

信号有三种处理方式,忽略、用户自定义、系统默认处理方式。

程序员可以通过下面一系列函数指定处理方式:

1. signal()

#include <signal.h> 
typedef void (*sig_t)(int); 
sig_t signal(int signum, sig_t handler);

//signum 为信号编号,handler 为处理方式,可为用户自定义的函数或以下参数
#define SIG_ERR ((sig_t) -1) /* Error return. */
#define SIG_DFL ((sig_t) 0) /* Default action. */
#define SIG_IGN ((sig_t) 1) /* Ignore signal. */

 2. sigaction()

#include <signal.h> 
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); 
};