1.信号发送函数
(1)alarm SIGALRM
unsigned int alarm(unsigned int seconds);
alarm函数,设置一个闹钟延迟发送SIGALRM信号(告诉Linux内核n秒中以后,发送SIGALRM信号);
(2)setitimer SIGALRM SIGVALRM SIGPROF
(3)abort SIGABRT
(4)kill命令 kill -ALRM `ps -aux | grep a.out | grep -v grep| awk '{ print $2}'`或者kill -14 pid或者kill -SIGALRM pid
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <signal.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#define ERR_EXIT(m) \
do \
{ \
perror(m); \
exit(EXIT_FAILURE); \
}while(0)
void handler(int sig);
int main () {
signal(SIGALRM, handler);
alarm(1);
for(;;) {
pause();
printf("pause return\n");
}
return 0;
}
void handler(int sig) {
printf("recv a sig=%d\n", sig);
alarm(1);
//sleep(1);
}
递归调用alarm
2.可重入函数
(1)为了增强程序的稳定性,在信号处理函数中应使用可重入函数。
(2)所谓可重入函数是指一个可以被多个任务调用的过程,任务在调用时不必担心数据是否会出错。因为进程在收到信号后,就将跳转到信号处理函数去接着执行。如果信号处理函数中使用了不可重入函数,那么信号处理函数可能会修改原来进程中不应该被修改的数据,这样进程从信号处理函数中返回接着执行时,可能会出现不可预料的后果。不可重入函数在信号处理函数中被视为不安全函数。
(3)满足下列条件的函数多数是不可重入的:
[1]使用静态数据结构,如getlogin(),gmtime(),getgrgid(),getgrnam(),getpwuid()以及getpwnam()等等;
[2]函数实现时,调用了malloc()或者free()函数;
[3]实现时使用了标准I/O函数
(4)man 7 signal可以查看那些函数是可重入和不可重入的
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <signal.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#define ERR_EXIT(m) \
do \
{ \
perror(m); \
exit(EXIT_FAILURE); \
}while(0)
typedef struct {
int a;
int b;
} TEST;
TEST g_data;
void handler(int sig);
int main () {
TEST zeros = {0, 0};
TEST ones = {1, 1};
signal(SIGALRM, handler);
g_data = zeros;
alarm(1);
for(;;) {
g_data = zeros;
g_data = ones;
}
return 0;
}
void unsafe_fun() {
printf("%d %d\n", g_data.a, g_data.b);
}
void handler(int sig) {
unsafe_fun();
alarm(1);
//sleep(1);
}