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

一、更多信号发送函数
(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没有完全修改完成的时候有可能被信号打断,造成输入结果和预期不一致。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值