十六、Linux系统编程-信号(三)其他信号发送函数、可重入及不可重入函数
2015-03-30 20:08
579 查看
一、更多信号发送函数
(1)、alarm 发送时钟信号
函数声明:
函数参数:
秒数
返回值:
由于调度剩余的秒数
示例:
(2)、setitimer 发送SIGALRM,SIGPROF,SIGVTALRM
函数声明:
函数参数:
返回值:成功返回0,失败返回-1并设置errno
(3)、abort 发送SIGABRT信号
函数声明:
函数参数:无
返回值:成功返回0,失败返回-1并设置errno
二、可重入函数与不可重入函数
所谓可重入函数是指一个可以被多个任务调用的过程,任务在调用时不必担心数据是否会出错。因为进程在收到信号后,就将跳转到信号处理函数去接着执行。如果信号处理函数中使用了不可重入函数,那么信号处理函数可能会修改原来进程中不应该被修改的数据,这样进程从信号处理函数中返回接着执行时,可能会出现不可预料的后果。不可再入函数在信号处理函数中被视为不安全函数。
满足下列条件的函数多数是不可再入的:(1)使用静态的数据结构,如getlogin(),gmtime(),getgrgid(),getgrnam(),getpwuid()以及getpwnam()等等;(2)函数实现时,调用了malloc()或者free()函数;(3)实现时使用了标准I/O函数的
为了增强程序的稳定性,在信号处理函数中应使用可重入函数。且应该降低信号处理函数的规模。
三、不可重入函数示例
示例:
(1)、alarm 发送时钟信号
函数声明:
#include <unistd.h> unsigned int alarm(unsigned int seconds);
函数参数:
秒数
返回值:
由于调度剩余的秒数
示例:
#include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <string.h> #include <stdio.h> #include <stdlib.h> #include <errno.h> #include <unistd.h> #include <signal.h> #define ERR_EXIT(m) \ do \ { \ perror(m); \ exit(EXIT_FAILURE); \ }while(0) void handle(int sig); int main(int argc,char* argv[]) { if ( signal(SIGALRM,handle) == SIG_ERR) ERR_EXIT("signal error"); alarm(2); for(;;) pause(); return 0; } void handle(int sig) { printf("recv a sig=%d\n",sig); alarm(2); }
(2)、setitimer 发送SIGALRM,SIGPROF,SIGVTALRM
函数声明:
#include <sys/time.h> int getitimer(int which, struct itimerval *curr_value); int setitimer(int which, const struct itimerval *new_value,struct itimerval *old_value);
函数参数:
返回值:成功返回0,失败返回-1并设置errno
(3)、abort 发送SIGABRT信号
函数声明:
#include <stdlib.h> void abort(void);
函数参数:无
返回值:成功返回0,失败返回-1并设置errno
二、可重入函数与不可重入函数
所谓可重入函数是指一个可以被多个任务调用的过程,任务在调用时不必担心数据是否会出错。因为进程在收到信号后,就将跳转到信号处理函数去接着执行。如果信号处理函数中使用了不可重入函数,那么信号处理函数可能会修改原来进程中不应该被修改的数据,这样进程从信号处理函数中返回接着执行时,可能会出现不可预料的后果。不可再入函数在信号处理函数中被视为不安全函数。
满足下列条件的函数多数是不可再入的:(1)使用静态的数据结构,如getlogin(),gmtime(),getgrgid(),getgrnam(),getpwuid()以及getpwnam()等等;(2)函数实现时,调用了malloc()或者free()函数;(3)实现时使用了标准I/O函数的
为了增强程序的稳定性,在信号处理函数中应使用可重入函数。且应该降低信号处理函数的规模。
三、不可重入函数示例
示例:
#include <unistd.h> #include <sys/stat.h> #include <sys/wait.h> #include <sys/types.h> #include <fcntl.h> #include <stdlib.h> #include <stdio.h> #include <errno.h> #include <string.h> #include <signal.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(int argc, char *argv[]) { TEST zeros = {0, 0}; TEST ones = {1, 1}; if (signal(SIGALRM, handler) == SIG_ERR) ERR_EXIT("signal error"); 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); }在这个程序中,在g_data没有完全修改完成的时候有可能被信号打断,造成输入结果和预期不一致。
相关文章推荐
- 信号编程之信号发送及信号处理函数遇到不可重入函数
- linux系统编程之信号(六):信号发送函数sigqueue和信号安装函数sigaction
- linux系统编程之信号:信号发送函数sigqueue和信号安装函数sigaction
- 【Linux系统编程】可重入函数和不可重入函数
- linux系统编程之信号(六):信号发送函数sigqueue和信号安装函数sigaction
- linux系统编程之信号(二):一些信号发送函数和不同精度的睡眠
- linux系统编程之信号(六):竞态条件与sigsuspend函数
- 十五、Linux系统编程-信号(二)信号分类、可靠信号与不可靠信号、信号发送 pause
- QThread 与 QObject的关系(QObject可以用于多线程,可以发送信号调用存在于其他线程的slot函数,但GUI类不可重入)
- linux 系统信号忽略和system函数返回值问题(system的实现)
- linux系统编程之信号(五):实时信号与sigqueue函数
- linux 系统编程之信号 test10_2.c
- Linux下C语言编程--信号处理函数
- linux 有关信号的系统调用 signal 等函数
- linux进程通信---几个发送信号的函数(kill,raise,alarm,pause)
- Linux系统文件I/O编程(一)---open()等基本函数
- linux系统编程之进程(三):exec系列函数
- UNIX(Linux)系统编程常用库函数说明
- Linux文件编程之--库函数pk系统调用函数
- linux系统编程之信号 test10_8.c