signal()信号测试

测试代码1:

# include <stdio.h>
# include <error.h>
# include <sys/types.h>
# include <string.h>
# include <signal.h>
typedef void Sigfunc(int);
void sig_usr(int signo){
	if(signo == SIGUSR1) printf("SIGUSR1 received.\n");
	else if(signo == SIGUSR2) printf("SIGUSR2 received.\n");
	//else if(signo == SIGTERM) printf("SIGTERM received.\n");
	else return;
	
}
int main(int argc, char *argv[]){
	if(signal(SIGUSR1, sig_usr) == SIG_ERR) perror("cant catch sigusr1");
	if(signal(SIGUSR2, sig_usr) == SIG_ERR) perror("cant catch sigusr2");
	//if(signal(SIGTERM, sig_usr) == SIG_ERR) perror("cant catch sigterm");
	for(;;) pause();
	return 0;
}

 

$ gcc unix.c -o unix

./unix &
[1] 4339

$ kill -SIGUSR1 4339
SIGUSR1 received.

$ kill -SIGUSR2 4339
SIGUSR2 received.

$ kill 4339

$
[1]+  已终止               ./unix

 sig_usr处理用户定义的信号SIGUSR1和SIGUSR2,kill指令向进程发送信号,由于进程没有处理终止信号,所以收到终止信号SIGTERM时程序默认被终止(代码注释部分就是处理终止信号的)。

 

测试代码2:进行信号处理函数时能否捕捉其他信号?

# include <stdio.h>
# include <error.h>
# include <errno.h>
# include <sys/types.h>
# include <string.h>
# include <signal.h>
typedef void Sigfunc(int);
void handler(){
	printf("begin SIGINT\n");
	for(int i=0; i<2000000000; ++i);
	printf("end SIGINT\n");
}
void handler2(){
	printf("begin SIGUSR1\n");
	printf("end SIGUSR1\n");
}
int main(int argc, char *argv[]){
	signal(SIGINT, handler);
	signal(SIGUSR1, handler2);
	pause();
	perror("done ");
	return 0;
}

$ ./unix &
[1] 3548
$ kill -SIGINT 3548
begin SIGINT
$ kill -SIGUSR1 3548
begin SIGUSR1
end SIGUSR1
$ end SIGINT
done : Interrupted system call

 结果显示为可以(另外经过测试在执行信号A的处理函数时是会阻塞信号A的到来的)。

测试代码3:sigaction函数代替signal函数

# include <stdio.h>
# include <error.h>
# include <errno.h>
# include <sys/types.h>
# include <string.h>
# include <signal.h>
typedef void Sigfunc(int);
void handler(){
	printf("handling singo.\n");
}
Sigfunc *signal(int signo, Sigfunc *func){
	struct sigaction act, oact;
	sigemptyset(&act.sa_mask);
	act.sa_flags = 0;
	act.sa_handler = func;
	if(signo == SIGALRM) act.sa_flags |= SA_INTERRUPT;
	else act.sa_flags |= SA_RESTART;
	if(sigaction(signo, &act, &oact) < 0) return SIG_ERR;
	return oact.sa_handler;
}
int main(int argc, char *argv[]){
	signal(SIGINT, handler);
	signal(SIGALRM, handler);
	alarm(8);
	char s[10]={0};
	read(0, s, sizeof(s));
	printf("%s\n",s);
	perror("done");
	return 0;
}

$ ./unix
^Chandling singo.
^Chandling singo.
^Chandling singo.
^Chandling singo.
handling singo.


done: Interrupted system call

 

 sigaction比signal提供了更多功能,包括阻塞信号sa_mask和状态位sa_flags,后者可以设置被信号中断的函数是否自动重启(比如低速系统调用read、write)。上面代码如果是alarm引起的中断不重启,其他重启,也就是8秒内read要返回,否则就跳过了。另外老版的signal函数只能生效一次,而sigaction函数能永久生效。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值