Linux remote development - use of signals (signal binding and sending)

content

1. The concept of signal

2. The signal() library function

Three, kill () function

1. Function

2. Function prototype

Fourth, reliable and unreliable signals

V. Summary


1. The concept of signal

        Signals are events generated by the UNIX system in response to certain conditions. The process will take corresponding actions when receiving signals. Signals are generated due to certain error conditions, such as memory segment conflicts, floating-point processor errors, or illegal instructions. . They are spawned by shells and terminal managers to cause interrupts. The purpose of a signal is to notify you to do something. For example, the alarm clock in the morning notifies you to get up, and the alarm clock acts as a signal.

You can view all signals by kill -l under linux

        As mentioned earlier, by killing -9 process ID, the process to which the ID belongs can be terminated. After learning the concept of signal, you can understand this command as sending the ninth signal to the process to which the ID belongs, informing him to do something. The ninth signal shown in the figure above is SIGKILL, that is, a signal to stop the process is sent to the process to which the ID belongs to notify it to stop, which is the so-called "kill" process.

        Numbers 1-31 are unreliable signals, and 34-64 are reliable signals. If the signal is sent continuously and uninterrupted, the signal will be lost as an unreliable signal , and if the signal is sent continuously and uninterrupted, the signal will not be lost as a reliable signal .

2. The signal() library function

        If you want the program to be able to handle signals, you can use the signal library function and import the header file <signal.h>. Enter the command man signal in the linux terminal to view his function prototype

        It can be seen that the first parameter signum of the signal() function is the signal number, that is, all signals that can be queried by kill -l, and the second parameter sighhandler is a function pointer.

        The signal to be captured or masked is given by the parameter signum, and the function to be called when the specified signal is received is given by sighandler. The sighandler function must have a parameter of type int ( that is, the received signal code ), the type of the function itself is void, and sighandler can also be the following two special values: SIG_IGN (mask the signal), SIG_DFL (restore the default behavior).

        In layman's terms, the function of the signal() library function is to bind a signal to a function . When the signal is sent, it will do the business of the bound function. Qt's signal and slot mechanism is implemented by borrowing this method.

Three, kill () function

1. Function

        The function of the kill function is to send the signal given by the parameter sig to the process whose identification number is pid. If the signal is bound to a function through sinal(), the process is temporarily interrupted to do the business of the bound function. After the business of the function is completed, the process continues to run.

        To send a signal, the sender process must have the appropriate permissions. This usually means that both processes must have the same user ID.

2. Function prototype

int kill(pid_t pid, int sig);

parameter:

pid: process ID

sig: a signal

return value:

Returns 0 on success and -1 on error.

Fourth, reliable and unreliable signals

Let's use a piece of code to verify reliable and unreliable signals

#include <iostream>
#include <unistd.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/wait.h>

using namespace std;

void signalfunction(int i);

int main()
{
	int pid = 0;
	int status = 0;
	//将信号和函数绑定在一起
	signal(SIGUSR1, signalfunction);
	pid = fork();
	if (pid == 0)//子进程
	{
		while(1)
		{
			cout << "子进程运行中 pid = " << getpid() << endl;
			sleep(1);
		}
	}
	else if(pid > 0)//父进程
	{
		sleep(3);//先让子进程先处理业务,测试kill函数
		for (int i = 1; i <= 5; i++)
		{
			cout << "父进程给子进程发送第 " << i << " 个信号" << endl;
			kill(pid, SIGUSR1);//给子进程发送信号
		}
		sleep(3);//延时3秒
		kill(pid, SIGKILL);//给子进程发送停止信号
		waitpid(pid, &status, 0);//等待子进程结束,防止子进程托孤
		cout << "子进程结束" << endl;
	}
	return 0;
}

void signalfunction(int i)
{
	cout << "函数被调用了 i = " << i << endl;
}

        The signal number 10 (SIGUSR1) and the signal number 12 (SIGUSR2) are both user signals that the programmer can use, and both signals are unreliable signals.

In the above code, the parent process sends a signal (SIGUSR1) 5 times         through a for loop , and the signal (SIGUSR1) is bound by the signal(SIGUSR1, signalfunction) and signalfunction() functions, that is to say, sending a signal once will Call this signalfunction() function once. The console output is as follows:

        It can be found that the parent process sends the signal 5 times, but the bound function is only executed once, that is, the phenomenon of signal loss occurs, which confirms that the signal is sent continuously and uninterrupted, and the signal will be lost as an unreliable signal , numbered 1- 31 are unreliable signals. At the same time, it can be found that the value of int type printed by the called function is exactly the number 10 of the unreliable signal ( SIGUSR1 ) .

        If you change signal( SIGUSR1 , signalfunction) to signal( SIGRTMIN , signalfunction), and send the signal kill(pid, SIGUSR1 ) to kill(pid, SIGRTMIN ) to continue the test, the console output is as follows:

        It can be found that the parent process has sent the signal 5 times, and the bound function has also been executed 5 times, that is, the signal has not been lost, which confirms that the signal is sent continuously and uninterrupted, and the signal will not be lost . The reliable signal is numbered 34-64 are reliable signals. The value of type int printed by the called function also happens to be the number 34 of that reliable signal ( SIGRTMIN ) .

V. Summary

1. The signal() function can bind a signal to a function.

2. The kill() function can send a signal to a child process with a certain ID, temporarily interrupt the child process, and turn to process the function business bound by the signal through the signal() function.

3. Those numbered 1-31 are all unreliable signals, and those numbered 34-64 are all reliable signals . The unreliable signal will lose the signal when the signal is sent continuously and uninterrupted, but the reliable signal will not have this phenomenon.

Originality is not easy, please indicate the source when reprinting.

If it is helpful to you, you can like, collect + follow, and it will be updated continuously (hee hee).

Guess you like

Origin blog.csdn.net/wmcy123/article/details/123587709