概述
信号不是很熟,要好好学习一下。
1.常用信号
SIGABRT
: 调用abort函数产生此信号
SIGALRM
: 调用alarm函数超时产生信号
SIGCHLD
: 子进程终止将发送该信号给父进程
SIGINT
: CTRL+C中断键
SIGSEGV
: 无效内存引用(Segmentation Fault)
SIGUSR1
: 用户自定义的信号,用于应用程序
2.信号处理
最简单的借口signal
函数:
#include <signal.h>
void (*signal(int signo,void (*func)(int)))(int);
typedef void (*sighandler_t)(int);
sighandler_t signal(int signum, sighandler_t handler);
signal
函数返回一个函数指针,该函数指针指向一个函数,该函数返回void,参数为int
signal
函数有两个参数,第一个参数是int,第二个参数是一个函数指针,该函数指针指向返回void,带一个参数int的函数
加上typedef
就清晰很多。
3.可重入函数
异步信号类似于硬件中断,主程序在执行时捕捉到信号,将进入信号处理函数中。
假设,当主程序正在malloc的时候,收到异步信号,在信号处理函数中继续调用malloc,结果是怎样的?
这种行为是不可预知的,因此malloc函数被称为不可重入的函数。
不可重入的函数有以下特性:
1.使用静态数据结构
2.调用malloc或者free
3.标准I/O函数
4.kill和raise函数
在终端调用kill命令可以向特定的进程发送信号。代码中可以使用raise
和kill
两个函数
#include <signal.h>
int kill(pid_t pid,int signo);
int raise(int signo);
raise
表示向本进程发送异步信号,等价于kill(getpid(),signo)
static void sig_usr(int signo)
{
if(signo == SIGUSR1)
{
printf("SIGUSR1 receivedrn");
}
else if(signo == SIGUSR2)
{
printf("SIGUSR2 receivedrn");
}
else
{
printf("received signal %drn",signo);
}
}
int main(int argc, char **argv)
{
if(signal(SIGUSR1,sig_usr)==SIG_ERR)
{
printf("SIGUSR1 ERROR rn");
return -1;
}
if(signal(SIGUSR2,sig_usr)==SIG_ERR)
{
printf("SIGUSR2 ERROR rn");
return -1;
}
kill(getpid(),SIGUSR1);
sleep(1);
raise(SIGUSR2);
sleep(1);
raise(SIGINT);//ctrl+c signal
sleep(10);//never execute
return 0;
}
5.alarm和pause函数
#include <unistd.h>
unsigned int alarm(unsigned int seconds);
这两个函数在之前的代码中有所涉及:
alarm
函数可以指定秒之后产生一个SIGALRM信号
pause
函数可以休眠直到收到异步信号
用他俩组合可以写一个sleep
函数
#include <signal.h>
#include <unistd.h>
static void sig_alrm(int signo)
{}
unsigned int sleep1(unsigned int seconds)
{
if(signal(SIGALRM,sig_alrm)==SIG_ERR)
return (seconds);
alarm(seconds);
pause();
return (alarm(0));
}
最后
以上就是火星上紫菜为你收集整理的Linux 信号signal(一)的全部内容,希望文章能够帮你解决Linux 信号signal(一)所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复