信号处理函数
?
信号发送函数—kill()
#include <sys/types.h>?
#include <signal.h>?
int kill(pid_t pid,int signo)?
?
#include <sys/wait.h>
#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
int main( void ) {
pid_t childpid;
int status;
int retval;
childpid = fork();
if ( -1 == childpid ){
perror( "fork()" );
exit( EXIT_FAILURE );
}
else if ( 0 == childpid ){
puts( "In child process" );
sleep( 100 );//让子进程睡眠,看看父进程的行为
exit(EXIT_SUCCESS);
}
else{
if ( 0 == (waitpid( childpid, &status, WNOHANG ))){
retval = kill( childpid,SIGKILL );
if ( retval ){
puts( "kill failed." );
perror( "kill" );
waitpid( childpid, &status, 0 );
}
else{
printf( "%d killed\n", childpid );
}
}
}
exit(EXIT_SUCCESS);
}
?信号发送函数—sigqueue()
仍然不支持排队,所有相同信号都被合并为一个信号
sigqueue()向信号传递附加消息的流程
?
Kill()与sigqueue()区别
信号发送函数—raise()
?
#include <stdio.h>
#include <signal.h>
int main(void)
{
printf("kill myself!\n");
raise(SIGKILL);
printf("can you see this?\n");
return 0;
}
信号发送函数—alarm()
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <stdlib.h>
#include <signal.h>
void handler() {
printf("hellon\n");
}
main()
{
int i;
signal(SIGALRM,handler);
alarm(5);
for(i=1;i<7;i++){
printf("sleep %d \n",i);
sleep(1);
}
}
信号发送函数—setitimer()
每间格一段时间就执行某个function
struct itimerval {
??? struct?? timeval?? it_interval;???? /*定时器周期*/
??? struct?? timeval?? it_value;??? /*定时器剩的时间,为0时发信号*/
};
struct timeval {
??? long? tv_sec;?? /*秒*/
??? long? tv_usec; /*微秒,1秒=1000000微秒*/
};
it_value为0是不会触发信号的,所以要能触发信号,it_value得大于0;如果it_interval为零,只会延时,不会定时(也就是说只会触发一次信号)。
#include <stdio.h>
#include <signal.h>
#include <sys/time.h>
void signalHandler(int signo)
{
switch (signo){
case SIGALRM:
printf("Caught the SIGALRM signal!\n");
break;
}
}
int main(int argc, char *argv[])
{
signal(SIGALRM, signalHandler);
struct itimerval new_value, old_value;
new_value.it_value.tv_sec = 1;
new_value.it_value.tv_usec = 0;
new_value.it_interval.tv_sec = 2;
new_value.it_interval.tv_usec = 0;
setitimer(ITIMER_REAL, &new_value, &old_value);
for(;;);
return 0;
}
信号发送函数—pause()
信号的安装(设置信号关联动作)
信号安装函数—signal()
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
void sig_usr(int sig);
int main(int argc, char* argv[])
{
int i=0;
if(signal(SIGUSR1, sig_usr) == SIG_ERR)
printf("Can't catch SIGUSR1\n");
if(signal(SIGUSR2, sig_usr) == SIG_ERR)
printf(“Can‘t catch SIGUSR2\n”);
while(1) {
printf("%2d\n", i);
pause();
i++;
}
return 0;
}
void sig_usr(int sig)
{
if(sig == SIGUSR1)
printf("Received SIGUSR1\n");
else if(sig == SIGUSR2)
printf("Received SIGUSR2\n");
else
printf("Undeclared signal %d \n",sig);
}
执行:
信号安装函数—sigaction()
int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact);
sigaction函数用于设定进程接收到特定信号后的行为。
?????????sigaction结构定义如下:
struct sigaction {
union{
__sighandler_t _sa_handler;
void (*_sa_sigaction)(int, struct siginfo *, void *);
}_u
sigset_t sa_mask;
unsigned long sa_flags;
void (*sa_restorer)(void);
}
?siginfo_t {
? ? ? ? ? ? ? ? ? int ? ? ?si_signo; ?/* 信号值,对所有信号有意义*/
? ? ? ? ? ? ? ? ? int ? ? ?si_errno; ?/* errno值,对所有信号有意义*/
? ? ? ? ? ? ? ? ? int ? ? ?si_code; ? /* 信号产生的原因,对所有信号有意义*/
? ? ? ? ? ? ? ? ? pid_t ? ?si_pid; ? ?/* 发送信号的进程ID,对实时信号以及SIGCHLD有 ? ? ? ? ? ? ? ?意义 */
? ? ? ? ? ? ? ? ? uid_t ? ?si_uid; ? ?/* 发送信号进程的真实用户ID,对kill(2),实时信号以及SIGCHLD有意义 */
? ? ? ? ? ? ? ? ? ?int ? ? ?si_status; /* 退出状态,对SIGCHLD有意义*/
? ? ? ? ? ? ? ? ? clock_t ?si_utime; ?/* 用户消耗的时间,对SIGCHLD有意义 */
? ? ? ? ? ? ? ? ? clock_t ?si_stime; ?/* 内核消耗的时间,对SIGCHLD有意义 */
? ? ? ? ? ? ? ? ? sigval_t si_value; ?/* 信号值,对所有实时有意义,是一个联合数据结构,
? ? ? ? ? ? ?/*可以为一个整数(由si_int标示,也可以为一个指针,由si_ptr标示)*/?? ?
? ? ? ? ? ? ? ? ?void * ? si_addr; ? /* 触发fault的内存地址,对SIGILL,SIGFPE,SIGSEGV,SIGBUS 信号有意义*/
? ? ? ? ? ? ? ? ?int ? ? ?si_band; ? /* 对SIGPOLL信号有意义 */
? ? ? ? ? ? ? ? ? int ? ? ?si_fd; ? ? /* 对SIGPOLL信号有意义 */
}
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
void myFun(int sig);
int main(int argc, char* argv[])
{
struct sigaction act, oldact;
act.sa_handler = myFun;
sigemptyset(&act.sa_mask);
act.sa_flags = 0;
sigaction(SIGUSR1, &act, &oldact);
while(1){
printf("Hello world!\n");
pause();
}
}
void myFun(int sig)
{
printf("I got a signal:%d\n",sig);
}
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <signal.h>
void func(int signo, siginfo_t *info, void *p)
{
printf("signo = %d\n", signo);
printf("sender pid = %d\n", info->si_pid);
}
int main()
{
struct sigaction act, oldact;
sigemptyset(&act.sa_mask);
act.sa_flags = SA_SIGINFO;
act.sa_sigaction = func;
sigaction(SIGUSR1, &act, &oldact);
while(1)
{
printf("pid is %d hello!\n",getpid());
pause();
}
}
?在另外一个终端发送信号给当前进程?
sigqueue()函数调用示例在不同进程间传递整型参数.信号接收程序
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <sys/types.h>
void myFun(int, siginfo_t*, void* myfun);
int main(int argc, char* argv[])
{
struct sigaction act;
int sig;
pid_t pid;
pid = getpid();
printf("pid is%d\n",pid);
sigemptyset(&act.sa_mask);
act.sa_sigaction = myFun;
act.sa_flags = SA_SIGINFO;
if(sigaction(SIGUSR1, &act, NULL)<0)
{
printf("install sig error\n");
return 0;
}
while(1)
{
sleep(2);
printf("wait for the signal\n");
}
}
void myFun(int signo, siginfo_t *info, void* myfun)
{
printf("the int value is %d\n",info->si_int);
printf("Recv signum is%d\n",signo);
//raise(SIGKILL);
}
sigqueue()函数调用示例在不同进程间传递整型参数.信号发送程序
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/time.h>
main(int argc, char* argv[])
{
pid_t pid;
int signum;
union sigval mysigval;
pid = (pid_t)atoi(argv[1]);
mysigval.sival_int = 8;
if(sigqueue(pid, SIGUSR1, mysigval)==-1)
printf("send error\n");
sleep(2);
return 0;
}
signal()与sigaction()的区别
信号集操作函数
查询信号signo是否在信号集set中
信号操作函数—sigprocmask( )
其他信号处理函数
task_struct中与信号处理相关的成员
定义TIF_RESTORE_SIGMASK时恢复信号掩码
task_struct信号处理相关数据结构关系图
?