Linux 8 signal sig

1. Signal concept

Signal (signal) is an interprocess communication mechanism that provides an asynchronous interrupt to the application software, the application has access to the command (ie, signal) other live programs sent by the terminal. Once the application is received signal, there are three approach: ignore, default, or capture. After the process receives a signal, it checks the signal processing mechanism. If SIG_IGN, to ignore the signal; if it is SIG_DFT, the system uses the default processing operation will usually terminate the process or ignore the signal; if the signal assigned to a handler (catch), it will interrupt the current process is tasks performed, turn to execute the signal handler, and then returns to continue the interrupted task.

2. Signal function

2.1 signal function

signal () function is the simplest installation signal processor to process the first parameter designation signal, the second parameter signal for a specified handler.

typedef void (*sighandler_t) (int)
sighandler_t signal(int signum, sighandler_t handler);

When using SIG_IGN as a signal to omit the second parameter
indicates the default process when used as a signal SIG_DFT second argument
if the call wrong, then it will return SIG_ERR and set errno. The only error code is EINVAL

2.2 sigaction function

sigaction function for changing the behavior of the process receives a particular signal. The first parameter is a function of the value of the signal can be any signal in addition to a particular valid SIGSTOP SIGKILL and outer (defined own handlers for the two signals will cause an error signal mounting). The second parameter is a pointer to an instance of the structure sigaction pointer, in the example structure sigaction, specify the processing of a particular signal, will be the default mode of the signal processing is empty, the process; third parameter points oldact the original object is used to save processing on the respective signals, can be specified oldact to NULL. If the second and third parameters are set to NULL, then the function can be used to check the validity of the signal.

int sigaction(int signum,const struct sigaction *act,struct sigaction *oldact));
struct sigaciton
{   
  void  (*sa_handler)(int);   
  void  (*sa_sigaction)(int ,siginfo_t *,void *);   
  sigset_t sa_mask;   
  int    sa_flags; 
}

sa_handler is to handle.
sa_sigaction also a handler address, when sa_flags set SA_SIGINFO when it works otherwise. with Handler
sa_mask specify a set of signals to be blocked during the signal handler execution, during execution sigaction will mask the signal.
sa_flags desirable the value is more, these are the following:
SA_NOCLDSTOP this flag is only valid for SIGCHLD signal, under normal circumstances, when the child process is stopped, always send a signal to the parent process, the child process is stopped when sometimes the recovery operation, to possible parent process to send a signal when signum is SIGCHLD when parameter passed by value, are no longer signals in both cases.
SA_RESTART If this flag is set and capture the signal, the system will automatically resume when the signal handler return the signal is interrupted system call. otherwise the interrupted system call will return -1 juxtaposed errno sa_flags SA_RESTART value. EINTR for the next. in most cases
a signal handler SA_ONSTACK If this flag is set, the system will run on the stack with the substitute signal sigaltstack specified. otherwise the user stack to deliver the signal.
SA_NODEFER If this flag is set and capture signals in During the execution system number does not automatically handles the blocking signal. This corresponds to the case of unreliable signal signal. (Estimated that no one will use this right ...)
SA_RESETHAND If this flag is set and capture the signal, the reset signal handler entrance system signal and clear action to SIG_DFL SA_SIGINFO flag and sigaction and signal behaves almost the same.
SA_NOCLDWAIT only work for SIGCHLD. If this flag is set, and sig is SIGCHLD, all child processes of the calling process is not transformed into zombie processes when terminating so the parent does not have to wait to call the function. If you call the process will always wait obstructive not return until all child processes end, the return value of -1 and set errno to ECHILD.
SA_SIGINFO not set with sa_handler and prohibit modifications sa_sigaction.

2.3 pause function

pause () makes the current process suspended until capture a signal, designated to ignore the signal, pause () does not return. Only performing a signal processing function, and its return, puase () it returns -1, and errno is set EINTR.

int pause(void);
2.4 raise function

Sends the specified signal to the current process

int raise(int sig);  
2.5 kill function

By sending a signal process number

int kill(pid_t pid,int sig);

pid> 0 sends a signal to the process ID for the pid
pid == 0 transmits a signal sent to a process belonging to a process group agreed that all the processes of
pid <0 sends a signal to all processes in process group ID is equal to the absolute value of the pid
pid = = -1 sends a signal to the process has permission to send in all the processes in the system

2.6 alarm function

Generating a clock signal SIGALRM

unsigned int alarm(unsigned int seconds);

alarm () function to set a timer, the timer expires SIGALRM signal is generated. Since each process can only have a SIGALRM handler, you can only set a timer for a process, so the alarm () and setitimer () handler will share the same SIGALRM signal and the signal. In other words, alarm () and setitimer () will affect each other. Call to alarm (), previously set timer will fail, and there is no time-out as the current return value of alarm. The clock is previously set to 100 seconds, when the current call alarm () 30 seconds have elapsed, the remaining 70 seconds as alarm () return value, and with alarm () number of seconds specified reset the timer. If seconds is zero, it will cancel the timer set previously, and leave the rest as value alarm () return value.

2.7 signal shielding the word

Each process will have a signal word shield, which defines the set of signals to block the current process. For each possible signal, the signal will have a masking word corresponding thereto, if the bit is set, the current signal is blocked. Process modification signal may be obtained and the current process by a mask character sigprocmask ().

signal.c

#include <stdio.h>        
#include <sys/types.h>        
#include <unistd.h>
#include <signal.h>

int flag = 1; 

/******************************************
*  函数名:func
*函数功能:信号处理函数
*输    入:信号
*输    出:无
*  返回值:无
*修改日期:2017-03-15
*修改作者:zzj
*******************************************/
void func(int sig) 
{
	printf("I get a signal:%d\r\n", sig);
	flag = 1;
}

/******************************************
*  函数名:main
*函数功能:signal的入口,安装进程处理器
*输    入:无
*输    出:无
*  返回值:OK
*修改日期:2017-03-15
*修改作者:zzj
*******************************************/
int main()
{
	/* 给进程安装信号处理器 */
	signal(1, func);
	signal(2, func);
	signal(3, func);
	signal(4, func);
	signal(5, func);
	printf("pid:%ld\n",(long)getpid());

	sleep(10);	/* 等待10s */
	
	raise(3);		/* 向当前进程发送信号 */
	
	while(flag)
	pause();		/* 挂起当前进程,等待信号 */
	
	return 0;
}

signal_send.c

#include <sys/time.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <signal.h>
#include <unistd.h>
#include <assert.h>

/******************************************
*  函数名:main
*函数功能:向指定进程号的进程发送用户输入的信号
*输    入:要发送信号的目标进程号
*输    出:无
*  返回值:无
*修改日期:2017-03-15
*修改作者:zzj
*******************************************/
int main (int argc, char **argv)
{
	int keyboard;
	int ret,i;
	char c;
	fd_set readfd;
	struct timeval timeout;
	
	keyboard = open("/dev/tty",O_RDONLY | O_NONBLOCK);
	assert(keyboard>0);
	
	while(1)
	{
		timeout.tv_sec=1;
		timeout.tv_usec=0;
		FD_ZERO(&readfd);
		FD_SET(keyboard,&readfd);

		ret=select(keyboard+1,&readfd,NULL,NULL,&timeout);
		if(FD_ISSET(keyboard,&readfd))
		{
			i=read(keyboard,&c,1);
			if('\n'==c)
				continue;
			printf("your input is %c\n",c);
			
			/* 在进程处理的函数中定义了信号1-5的处理 */
			if (c >= '1' && c <= '5')
				kill(atoi(argv[1]), c - '1' + 1);
			
			if ('q'==c)
			{
				kill(atoi(argv[1]), SIGKILL);	/* SIGKILL为9 */
				break;
			}
		}
	}
}

Makefile


APP_NAME = signal
APP_OBJS = signal.o
CC = gcc
INC = ./
CFLAG += -g

.PHONY : all

all : $(APP_NAME) signal_send

$(APP_NAME) : $(APP_OBJS)
	$(CC) $(CFLAG) $(APP_OBJS) -o $(APP_NAME)

signal_send : signal_send.o
	$(CC) $(CFLAG) $^ -o $@
	
%.o : %.c
	$(CC) -c $(CFLAG) $^ -o $@

.PHONY : clean

clean :
	rm -f .o
	rm -f $(APP_NAME) $(APP_OBJS) signal_send

Guess you like

Origin blog.csdn.net/zzj244392657/article/details/92567530