您的位置:首页 > 运维架构 > Linux

十六、Linux系统编程-信号(三)其他信号发送函数、可重入及不可重入函数

2015-03-30 20:08 579 查看
一、更多信号发送函数
(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没有完全修改完成的时候有可能被信号打断,造成输入结果和预期不一致。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: