首页 > 其他 > 详细

sigaction和sigqueue

时间:2017-01-05 09:48:02      阅读:321      评论:0      收藏:0      [点我收藏+]

sigaction函数相对于siganl函数控制信号的发送要更加精确一些,其函数原型为:

int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact);

实验代码:

#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>

/* 信号处理函数:信号量,发送者传递的额外信息,参数 */
void func_handler(int signum, siginfo_t *info, void *arg)
{
	printf("/nget the signal. pid : %d, uid : %d\n", info->si_pid, info->si_uid);
	printf("sival_int : %d\n", (int)arg);
	/* printf("si_signo : %d, si_code : %d, si_errno : %d\n", info->si_signo, info->si_code, info->si_errno); 

*/
	printf("si_status : %d\n", info->si_status);
        /* printf("si_utime : %d, si_stime : %d\n", info->si_utime, info->si_stime); */
	printf("signal from address : 0x%x\n", info->si_addr);
	printf("--------++++++++--------\n");
}

int main(int argc, char *argv[])
{
	struct sigaction signal_action;
	/* initializes the signal set given by set to empty, with all signals excluded from the set */ 
	/* 初始化sigaction */
	sigemptyset(&signal_action.sa_mask); 

	signal_action.sa_sigaction = func_handler; /* 设置信号处理函数 */
	/* 设置标志位 */
	/* SA_SIGINFO:信号发送者会提供额外的信息(siginfo_t),信号处理函数应该使用三参数(int,siginfo_t *,void *) */
	/* SA_RESTART:如果系统调用被信号中断,则不返回错误,而是自动重启系统调用(重入机制) */
	signal_action.sa_flags |= SA_SIGINFO | SA_RESTART;
	
	/* The  sigaction(int, const struct sigaction *new, struct sigaction *old)  system call is used to change 

the action taken by a process on receipt of a specific signal */
	/* 修改信号的处理函数 */
	if(sigaction(SIGINT, &signal_action, NULL) == -1)
	{
		printf("sigaction failed, app exit. error : %s!\n", strerror(errno));
		exit(1);
	}
	while(1)
	{
		/* 暂停进程,或注释掉该行代码 */
		pause();
	}
	printf("done!\n");

	return 0;
}

运行程序后,使用命令:ps -au查看该程序的进程编号

技术分享

使用sigqueue函数向指定进程发送指定信号,实验代码:

#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>

int main(int argc, char *argv[])
{
	union sigval arg;
	arg.sival_int = 2017; /* sigqueue指定的整型参数 */
	int pid = atoi(argv[1]); /* 指定一个进程编号 */
	int sig = atoi(argv[2]); /* 指定一个信号 */

	printf("pid : %d, sig : %d\n", pid, sig);

	/* 检测该进程是否存在 */
	if(sigqueue(pid, 0, arg) != 0)
	{
		printf("no process‘s pid : %d, app exit!\n", pid);
		exit(-1);
	}
	printf("check process succeed!\n");


	int times = 0;
	for(;times<3;times++)
	{
		printf("sending a signal : [%d] to process : [%d].\n", sig, pid);
		if(sigqueue(pid, sig, arg) == -1)
		{
			printf("sigqueue failed, app exit. err : %s!\n", strerror(errno));
			exit(-1);
		}
		printf("times : %d, sigqueue success, sleep 2 second!\n", times + 1);
		sleep(2);
	}
	
	return 0;
}

使用命令./sigqueue 32499 2, 意思是对进程32499进程发送SIGINT(2)信号

技术分享

sigqueue进程每隔2秒发送一个SIGINT信号,sigaction进程就显示了信号发送者的额外信息.

当然,也可以通过kill命令向指定的进程发送指定的信号,比如

技术分享

 

sigaction和sigqueue

原文:http://www.cnblogs.com/foggia2004/p/6251172.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!