信号是一种软件中断,是一种处理进程间异步的通信机制。信号可以导致一个正在运行的进程被另一个异步进程中断,转而处理某一个突发事件。
常见的信号
kill -l 命令查看
1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL 5) SIGTRAP
6) SIGABRT 7) SIGBUS 8) SIGFPE 9) SIGKILL 10) SIGUSR1
11) SIGSEGV 12) SIGUSR2 13) SIGPIPE 14) SIGALRM 15) SIGTERM
16) SIGSTKFLT 17) SIGCHLD 18) SIGCONT 19) SIGSTOP 20) SIGTSTP
21) SIGTTIN 22) SIGTTOU 23) SIGURG 24) SIGXCPU 25) SIGXFSZ
26) SIGVTALRM 27) SIGPROF 28) SIGWINCH 29) SIGIO 30) SIGPWR
31) SIGSYS
通常对于一个进程发送信号时
//用一个简单的死循环验证,当按下组合键ctrl-c时,就是向该进程发送了一个信号,终止该进程。
#include
int main()
{
while(1)
{
printf("pid is %d\n",getpid());
sleep(1);
turn 0;
}
#include
int main()
{
int a=10;
int b=a/0;
printf("b=%d\n",b);
return 0;
}
//进行了除0的操作,硬件异常产生信号SIGFPE,进程异常退出
进程运行后异常退出,并显示core dumped。
core dumped:表示一个进程异常退出,操作系统会将异常信息转储到硬盘上,是便于gdb调试。
- 终止进程信号。进程调用kill函数可以发生信号给另一个进程,也可以kill命令发送信号给某个进程。
//任意进程之间发送任意信号
#include
#include
int kill(pid_t pid, int sig);
//pid是传递信号的进程号,sig为发送的信号值
//一个进程给自己发送任意信号
#include
int raise(int sig)
//一个进程给自己发送唯一信号
#include
void abort(void);
//特定时间后给进程发送信号(SIGALRM),该信号的默认动作是终止该进程
#include
unsigned int alarm(unsigned int seconds);
//函数的返回值是0或设定的闹钟剩余的秒数
#include
typedef void (*sighandler_t)(int);
sighandler_t signal(int signum, sighandler_t handler);
//信号处理函数,第一个参数为接收到的信号,第二个参数函数指针使接收到信号后处理代码入口。
#include
int sigemptyset(sigset_t *set);
//对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);
//检测信号集是否为空
#include
int sigprocmask(int how, const sigset_t *set, sigset_t *oldset);
//读取或改变进程的信号屏蔽字。成功返回0,失败则返回-1.
如果oldset非空,则读取进程当前的信号屏蔽字通过oldset传出。如果set非空,则更改进程的信号屏蔽字,参数how表示如何更改。如果set和oldset都非空,则先将原来的屏蔽字备份到oldset,再根据set和how参数更改屏蔽字。
how含义
#include
int sigpending(sigset_t *set);
//读取当前进程的未决信号集,通过set参数传出。成功返回0,失败返回-1
#include
int sigpending(sigset_t *set);
//读取当前的未决信号,通过set传出
代码实现:
#include
#include
#include
void printsigset(sigset_t *set)
{
int i=0;
for(i=1;i<=31;i++)
{
if(sigismember(set,i))//检测该信号是否存在与
{
printf("1");
}
else
{
printf("0");
}
}
printf("\n");
}
void handler(int sig)
{
printf("get a sig%d\n",sig);
}
int main()
{
sigset_t blockset,oblockset,pending;
//定义三个信号集,其中pending是用来获取未决信号集的
sigemptyset(&blockset);
sigemptyset(&oblockset);//将blocket,oblocket初始化清空置零
sigaddset(&blockset,2);//将2号信号添加到blocket信号集中
signal(2,handler);
sigprocmask(SIG_SETMASK,&blockset,&oblockset);//将2号信号block阻塞,将原来的值读到oblockset
int count=0;
while(1)
{
sigpending(&pending);//获取当前的未决信号
printsigset(&pending);//并显示出来
sleep(1);
if(++count==10)
{
//printf("recover proc block set\n",count)
sigprocmask(SIG_SETMASK,&oblockset,NULL);//当count加到10时,对pending表进行操作,当前的屏蔽字为oblockset对应的信号集,也就是清除对2号信号的阻塞,也就还原回去。
}
}
}