信号处理函数
信号发送函数—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()
#include <signal.h>
int sigqueue(pid_t pid , int signo , const union sigval sigval_t )
仍然不支持排队,所有相同信号都被合并为一个信号
sigqueue()向信号传递附加消息的流程
Kill()与sigqueue()区别
信号发送函数—raise()
int raise(int signo)
#include <stdio.h>
#include <signal.h>int main(void)
{printf("kill myself!\n");raise(SIGKILL);printf("can you see this?\n");return 0;
}
信号发送函数—alarm()
unsigned int alarm(unsigned int seconds)
#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");elseprintf("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 *);}_usigset_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信号处理相关数据结构关系图