信号完结
This commit is contained in:
@@ -15,6 +15,9 @@
|
||||
> 信号是软件中断。
|
||||
信号的响应依赖于中断。
|
||||
|
||||
信号的处理函数应该尽量短小,注意是否可重入问题。
|
||||
使用系统调用,不能轻易使用IO。
|
||||
|
||||
```bash
|
||||
kill -l # 查看信号列表
|
||||
```
|
||||
@@ -31,8 +34,8 @@ typedef void (*sighandler_t)(int);
|
||||
|
||||
/**
|
||||
* signal - 设置信号处理函数
|
||||
* @signum: 信号编号
|
||||
* @handler: 信号处理函数
|
||||
* @param: signum 信号编号
|
||||
* @param: handler 信号处理函数
|
||||
*
|
||||
* 返回值:原信号处理函数
|
||||
*/
|
||||
@@ -91,6 +94,10 @@ M P
|
||||
有则重复,无则将M置1,回到常规状态。
|
||||
1 0
|
||||
|
||||
不能从信号处理函数中随意的往外跳。(setjmp, longjmp)
|
||||
这样错过了将M置1的机会。
|
||||
标准:sigsetjmp, siglongjmp, 推出这俩来保存掩码情况。
|
||||
|
||||
### 常用函数
|
||||
|
||||
```c
|
||||
@@ -119,7 +126,7 @@ int kill(pid_t pid, int sig);
|
||||
|
||||
/**
|
||||
* raise - 发送信号给当前进程
|
||||
* @sig: 信号编号
|
||||
* @param: sig 信号编号
|
||||
*
|
||||
* 返回值:成功返回0,失败返回非零
|
||||
*/
|
||||
@@ -168,22 +175,88 @@ void abort(void);
|
||||
*/
|
||||
int system(const char *command);
|
||||
|
||||
sleep();
|
||||
|
||||
/**
|
||||
* sleep - 休眠进程
|
||||
* @param: seconds: 休眠时间,单位为秒
|
||||
*
|
||||
* @note: 休眠当前进程,直到指定的时间段结束
|
||||
*
|
||||
* @return: 剩余时间,单位为秒
|
||||
*/
|
||||
unsigned int sleep(unsigned int seconds);
|
||||
// 可以封装出sleep函数
|
||||
int nanosleep(const struct timespec *req, struct timespec *rem);
|
||||
int usleep(useconds_t usec);
|
||||
int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);
|
||||
```
|
||||
|
||||
### 信号集
|
||||
|
||||
```c
|
||||
struct sigset_t; // 信号集类型
|
||||
int sigemptyset(sigset_t *set);
|
||||
int sigfillset(sigset_t *set);
|
||||
int sigaddset(sigset_t *set, int signum);
|
||||
int sigdelset(sigset_t *set, int signum);
|
||||
int sigismember(const sigset_t *set, int signum);
|
||||
```
|
||||
|
||||
### 信号屏蔽字/`pending`的处理
|
||||
|
||||
```c
|
||||
/**
|
||||
* sigprocmask - 设置信号掩码
|
||||
* @param: how: 掩码操作类型
|
||||
* @param: set: 信号集指针
|
||||
* @param: oldset: 旧的信号集指针
|
||||
*/
|
||||
int sigprocmask(int how, const sigset_t *set, sigset_t *oldset);
|
||||
|
||||
/**
|
||||
* sigpending - 获取未决信号集
|
||||
* @param: set: 信号集指针
|
||||
* @note: 该函数获取当前进程的未决信号集
|
||||
* 该函数会清空pending信号集,并将其复制到set指向的信号集中。
|
||||
* 该函数不修改信号掩码。
|
||||
*
|
||||
* !!!: 没有使用场景,不推荐使用
|
||||
* 取到的信号是响应之前的信号,等取到的时候,情况可能已经变化。
|
||||
*/
|
||||
int sigpending(sigset_t *set);
|
||||
```
|
||||
|
||||
### 扩展
|
||||
|
||||
```c
|
||||
sigsuspend();
|
||||
sigaction();
|
||||
/**
|
||||
* sigwait - 等待信号
|
||||
*/
|
||||
int sigsuspend(const sigset_t *mask);
|
||||
|
||||
/**
|
||||
* setitimer - 设置定时器
|
||||
* sigaction - 设置信号处理函数,替代signal
|
||||
* @param: signum: 信号编号
|
||||
* @param: act: 信号处理函数
|
||||
* @param: oldact: 旧的信号处理函数
|
||||
*
|
||||
* @note: signal无法区分信号来自user还是kernel
|
||||
* sigaction可以区分
|
||||
* 看siginfo_t.si_code可以区分
|
||||
*/
|
||||
int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact);
|
||||
|
||||
struct sigaction {
|
||||
//!在某些结构, sa_handler和sa_sigaction只能有一个被设置
|
||||
//!因为他们是共用体
|
||||
void (*sa_handler)(int); /* 信号处理函数 */
|
||||
void (*sa_sigaction)(int, siginfo_t *, void *); /* 信号处理函数 */
|
||||
sigset_t sa_mask; /* 信号掩码 */
|
||||
int sa_flags; /* 信号标志 */
|
||||
void (*sa_restorer)(void); /* 信号状态恢复函数 */
|
||||
};
|
||||
|
||||
/**
|
||||
* setitimer - 设置定时器,替代alarm
|
||||
* @param: which: 定时器类型
|
||||
* ITIMER_REAL : 实时定时器
|
||||
* ITIMER_VIRTUAL : 虚拟定时器
|
||||
@@ -216,4 +289,14 @@ struct timeval {
|
||||
|
||||
### 实时信号
|
||||
|
||||
查看信号
|
||||
|
||||
- `kill -l`
|
||||
- `cat /usr/include/bits/signum-generic.h`
|
||||
|
||||
1. 排队
|
||||
2. 不丢失
|
||||
|
||||
此外都和标准信号一样
|
||||
|
||||
## 线程(强烈异步)
|
||||
|
||||
Reference in New Issue
Block a user