Linux-信号

1、定义  

信号
引用APUE第二版中所述,信号就是软件中断,提供了一种处理异步事件的方法。沿用《Linux高性能服务器编程》中对于信号的定义,信号是由用户、系统或进程发送给目标进程的信息。例如用户在Shell中执行程序A(非后台进程),可以通过Ctrl+C的方式给程序A发送一个SIGINT中断信号,默认情况下程序A为被终止掉。
  在Linux系统中中,总共有31个标准信号,全部被定义在头文件<bits/signum.h>中,常用的主要有如下几种:
信号 含义 默认
SIGHUP 控制终端挂起 终止
SIGINT 系统中断 终止
SIGABRT 系统异常终止 终止
SIGCLD 子进程状态改变 忽略
SIGCHLD 与SIGCLD相同  
 
信号集是一组信号的集合,linux中使用sigset_t来表示。
 

2、函数

①、信号函数

int kill (__pid_t __pid, int __sig) 发送信号
给指定的进程发送sig信号,如果pid=0则发送给本进程组中的其他进程。 如果pid=-1发送给除去init进程之外的所有进程,pid<-1信号发送给组ID为-pid进程组中所有成员。
int sigaction (int __sig, const struct sigaction *__restrict __act, struct sigaction *__restrict __oact) 处理信号
指定__act 函数为信号sig的默认处理函数。同时返回旧的信号处理函数。
信号处理函数有SIG_DFL(使用信号默认处理) SIG_IGN(忽略信号)
 
②、信号集处理函数(POSIX标准)
int sigemptyset (sigset_t *__set) 信号集置空
int sigfillset (sigset_t *__set) 设置所有信号
int sigaddset (sigset_t *__set, int __signo) 增加信号
int sigdelset (sigset_t *__set, int __signo) 删除信号
int sigismember (const sigset_t *__set, int __signo) 判断是否信号是否属于信号集
int sigprocmask (int __how, const sigset_t *__restrict __set, sigset_t *__restrict __oset) 设置进程信号集掩码,被屏蔽的信号将不会被进程接受。
int sigpending (sigset_t *__set) 取消信号挂起
 

3、例子

① 让程序忽略某个信号
    struct sigaction sa;
    sa.sa_handler = SIG_IGN;  // 忽略信号
    sigemptyset(&sa.sa_mask);
    sa.sa_flags = 0;
    sigaction(SIGHUP, &sa, NULL);

 

② 守护程序启动异常终止的子程序
main.c
int main(int argc, char *argv[]) {
	set_Daemon();
	start_main();

	return 1;
}

int start_main(){
    // add your code
}

int set_Daemon(){
	// clear file create mask
	umask(0);

	struct rlimit rl;
	pid_t pid;

	// get the open file describle number limit
	if(getrlimit(RLIMIT_NOFILE, &rl)<0){
		printf("get the limits err\n");
		return -1;
	}

	// create a new  session. create a child process, and the parent process quit
	if( (pid = fork()) <0) {
		printf("fork error\n");
		return -1;
	}
	else if(pid!=0){
		printf("fork ok, parent out\n");
		exit(0);
	}
	printf("fork ok, child continue\n");
	setsid();

	// signal handle, igore the sighup signal
	struct sigaction sa;
	sa.sa_handler = SIG_IGN;
	sigemptyset(&sa.sa_mask);
	sa.sa_flags = 0;
	sigaction(SIGHUP, &sa, NULL);

	if( (pid = fork()) <0) {
		printf("fork error\n");
		return -1;
	}
	else if(pid!=0){
		exit(0);
	}

	chdir("/");

	// close all the file descriptors
	if(rl.rlim_max>1024){
		rl.rlim_max = 1024;
	}
	for(int i=0; i<rl.rlim_max; i++){
		close(i);
	}

	// attach 0,1,2 file descriptor to /dev/null
	int fd0, fd1, fd2;
	fd0 = open("/dev/null", O_RDWR);
	fd1 = dup(0);
	fd2 = dup(0);
}

int set_signal(){
	signal(SIGABRT, restart);
	signal(SIGINT, restart);
	signal(SIGCLD, restart);
	signal(SIGCHLD, restart);
}

void restart(int sig){
	if(sig==SIGABRT){
		printf("get the SIGABRT signal\n");
	}
	else if(sig==SIGCLD || sig==SIGCHLD){
		printf("get the SIGCLD|SIGCHLD signal\n");
	}
	else if(sig==SIGINT){
		printf("get the SIGINT signal\n");
		exit(-1);
	}
}

  

posted @ 2016-08-25 20:51  IT人生路漫漫  阅读(158)  评论(0)    收藏  举报