目录
1 概念
2 信号类型
linux的基本信号类型
操作 常用的信号
3 怎么操作信号
signal
kill
raise
alarm
pause
注意
范例1(自己用信号发送书写sleep函数实现定时炸弹)
范例2(用信号发送书写功能检测用户是否输入,如果用户3s内没有输入,则超时一次,如果超时 3次则自动退出。)
1 概念
进程间通信,用来发送通知(异步通信,中断)
内核层给用户层传递消息,通过发送信号实现
硬件
同步通信:发送端和接收端,使用同一时钟通信
异步通信:发送端和接收端使用不同时钟通信软件
同步通信:按照指定的顺序进行运行
异步通信:一种随机事件,在程序编写阶段不能够确定事件发生的时机
2 信号类型
linux的基本信号类型
操作 常用的信号
2)SIGINT:中断信号(可以在终端按ctrl + c输入)
3)SIGQUIT:退出信号(可以在终端按ctrl + \输入)
9)SIGKILL:杀死信号
11)SIGSEGV:段错误信号
13)SIGPIPE:管道破裂信号
14)SIGALRM:定时信号
17)SIGCHLD:当前进程有子进程结束(子进程结束,操作系统会给父进程发送SIGCHLD)
18)SIGCONT:继续执行信号
19)SIGSTOP:暂停信号
29)SIGIO:异步IO信号
20)SIGTSTP:挂起信号(可以在终端按ctrl + z输入)
10) SIGUSR1 专门预留给程序员使用的未定义信号。
12 )SIGUSR2 专门预留给程序员使用的未定义信号。
3 怎么操作信号
信号发送方
用以下函数实现操作
kill
raise
alarm
pause
...
信号接收方
每个进程都会对信号做出默认响应,但是不是唯一响应。
一般对信号的处理方法有三种:
1.缺省
按照默认方式处理信号
2.忽略
不处理信号
3.捕捉
按照自定义方式处理信号
特殊的:9)SIGKILL和19)SIGSTOP 不能被忽略和捕捉
signal
typedef void (*sighandler_t)(int);
sighandler_t signal(int signum, sighandler_t handler);
功能:
注册一个信号并设置信号的处理方式
参数:
signum:信号的编号
handler:信号的处理方式 捕获
SIG_IGN 忽略
SIG_DFL 缺省
信号对应的处理函数地址
返回值:
成功返回上一次注册的信号处理函数
失败返回SIG_ERR
kill
int kill(pid_t pid, int sig);
功能:
给进程发送信号
参数:
pid:进程的ID号
sig:信号的Id
返回值:
成功返回0
失败返回-1
raise
int raise(int sig);
功能:
给自己发送一个sig信号
参数:
sig:信号的ID
返回值:
成功返回0
失败返回-1
alarm
unsigned int alarm(unsigned int seconds);
功能:
过seconds秒后给自己发送一个SIGALRM信号
参数:
seconds:过seconds秒后发送信号
返回值:
上次定时剩余的时间比如:alarm(0);
关闭定时
pause
int pause(void);
功能:
让调用pause的进程或线程挂起
参数:
缺省void
返回值:
失败返回-1
注意
注意:
1.pause挂起后,收到信号才能被唤醒
2.信号不能按默认方式处理,否则进程任务会结束,应该改为捕捉信号
范例1(自己用信号发送书写sleep函数实现定时炸弹)
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
#include <semaphore.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <signal.h>
#include <sys/ipc.h>
#include <sys/shm.h>
void handle(int arg)
{
}
int Mysleep(int n)
{
signal(SIGALRM, handle);
int i = alarm(n);
pause();
return 0;
}
int main(int argc, char const *argv[])
{
int i = 10;
while(i--)
{
printf("炸弹%d秒后爆炸\n",i);
Mysleep(1);
}
printf("爆炸\n");
return 0;
}
一秒打印一句
范例2(用信号发送书写功能检测用户是否输入,如果用户3s内没有输入,则超时一次,如果超时3次则自动退出。)
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
#include <semaphore.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <signal.h>
#include <sys/ipc.h>
#include <sys/shm.h>
int times = 3;
void handle(int arg)
{
if(0 == times)
{
exit(0);
}
else
{
times--;
printf("你还有%d次输入机会\n",times);
alarm(3);
}
}
int main(int argc, char const *argv[])
{
char tmp[1024] = {0};
signal(SIGALRM,handle);
while (1)
{
alarm(3);
fgets(tmp,sizeof(tmp),stdin);
times = 3;
}
return 0;
}
运行结果可以看到,我只要三秒不输入就会扣除一次输入机会,倘若输入了,就会重新又三次机会,如果三次机会后都没有输入就会退出程序。