signal/kill

All signals received by each process are sent and processed by the kernel.

The blocking signal set is the set         of signals to be blocked by the current process , and the pending signal set is the set of signals that are still pending in the current process. These two sets are stored in the PCB of the kernel.

        Each signal has two flag bits indicating blocking and pending, and a function pointer indicating processing action. When a signal is generated, the kernel sets the pending flag of the signal in the process control block and does not clear the flag until the signal is delivered.

Take SIGINT as an example to illustrate the relationship between the pending signal set and the blocked signal set:        

  • When the process receives a SIGINT signal (signal number 2), first the signal will be saved in the pending signal set. At this time, the position of the corresponding number 2 is set to 1, indicating that it is in a pending state;
  • Before this signal needs to be processed, first check whether the value is 1 at position number 2 in the blocking signal set: if it is 1, it means that the SIGNIT signal is blocked by the current process. This signal is not processed temporarily, so it is pending. The value at this position in the signal set remains 1, indicating that the signal is in a pending state; if it is 0, it indicates that the SIGINT signal is not blocked by the current process, this signal needs to be processed, and the kernel will process the SIGINT signal (perform the default action , ignore or execute user-defined signal processing functions), and change the position numbered 2 in the pending signal set from 1 to 0, indicating that the signal has been processed. This time is very short and cannot be perceived by the user.        
  • When the SIGINT signal is unblocked from the blocked signal set, the signal will be processed. 

signaling mechanism

        A sends a signal to B, and B executes its own code before receiving the signal. After receiving the signal, no matter where in the program it is executed, it must pause to process the signal, and then continue execution after processing. Similar to hardware interrupt - asynchronous mode. But signals are interrupts implemented at the software level, and were often called "soft interrupts" in the early days.

 Events and status related to signals

Generate signal :

        1. Key press generation, such as: Ctrl+c, Ctrl+z, Ctrl+\

        2. System calls are generated, such as: kill, raise, abort

        3. Software conditions are generated, such as: timer alarm

        4. Hardware exceptions occur, such as: illegal memory access (segmentation fault), division by 0 (floating point exception), memory alignment error (bus error)

        5. Command generation, such as: kill command

Delivery : Delivery and arrival process.

Pending : The state between creation and delivery. This state is mainly caused by blocking (shielding).

Signal processing method

1. Execute default action

2. Ignore (discard)

3. Capture (call user processing function)

        The process control block PCB of the Linux kernel is a structure, task_struct. In addition to containing the process id, status, working directory, user id, group id, and file descriptor, it also contains signal-related information, mainly referring to blocking signal sets and pending signals. signal set.

        The pending signal set is a signal that has not been processed. The pending signal set is actually a 32-digit number. Each bit represents a signal. When the signal is generated, the corresponding bit is inverted to 1. If the signal is not If it is processed, it will be flipped back to 0, and if it is processed, it will remain 1.

        The blocked signal set affects the pending signal set. For example, if I set signal No. 2 to 1 in the blocked signal set, that is, signal No. 2 is blocked, then the bit corresponding to signal No. 2 in the pending signal set will become 1 (pending state), always blocked in this state.

        The kernel determines whether the signal should be processed by reading the pending signal set . The signal mask word mask can affect the pending signal set, and we can customize the set in the application to change the mask to achieve the purpose of blocking the specified signal. 

        In summary, the pending signal set is a collection of unprocessed signals in the current process. It is a 32-bit word. Each bit of the changed word corresponds to a signal. If the bit is 1, it means that the signal has not been processed. If it is changed to Set to 0, indicating that the signal has been processed or the signal has not been delivered.

        The blocking signal set is a 32-bit signal masking word that blocks or shields the signal. Similarly, each bit corresponds to a signal. If a certain bit is set to 1, then the signal corresponding to the bit will be blocked, and the signal will be Delayed processing. If a signal is generated at this time, the corresponding position in the pending signal set is 1. The signal will not be processed until the signal is unblocked (that is, the corresponding position in the blocked signal set is 0). After processing the signal , the corresponding bit in the pending signal set is inverted back to 0. 

4 signal elements

Similar to the three elements of variables, each signal also has its necessary four elements, which are:                

        1. Number 2. Name 3. Event 4. Default processing action

 kill command and kill function

 The kill command generates a signal: kill -SIGKILL pid

 Kill function : Send a specified signal to the specified process (not necessarily kill it)

         int kill (pid_t pid, int sig);       

                Success: 0;

                Failure: -1 (illegal ID, illegal signal, normal user killing init process and other privilege level issues), set errno

         sig: It is not recommended to use numbers directly, macro names should be used, because the signal numbers of different operating systems may be different, but the names are consistent.

        pid > 0: Send signal to the specified process.

             = 0: Send the signal to all processes belonging to the same process group as the process calling the kill function.

             < -1: Get |pid| and send it to the corresponding process group.

             = -1: Send to all processes in the system that the process has permission to send.

 Case 1: Use the kill function to terminate any process

Exercise: Create 5 child processes in a loop, and the parent process uses the kill function to terminate any child process.

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <signal.h>
#define N 5
int main(void)
{
    int i;
    pid_t pid, q;	
    for (i = 0; i < N; i++) 
	{
        pid = fork();
        if (pid == 0)
        {
			break;
        }	
        if (i == 2)
            q = pid;
    }
    if (i < 5) 
    {            //子进程

            printf("I'm child %d, getpid = %u\n", i, getpid());
            sleep(10);	
    } 
	else 
	{                //父进程
        sleep(3);
        kill(q, SIGKILL);
        printf("------------kill %d child %u finish\n", 2, q);
        while (1);
    }	
    return 0;
}

Software conditions generate signals

alarm function 

Set a timer (alarm clock). After specifying seconds, the kernel will send the 14) SIGALRM signal to the current process. When the process receives this signal, the default action is to terminate.

Each process has one and only one timer.

unsigned int alarm(unsigned int seconds);

        Returns 0 or the number of seconds remaining without failure.

Commonly used: cancel timer alarm(0) and return the remaining seconds of the old alarm clock.

          例:alarm(5) → 3sec → alarm(4) → 5sec → alarm(5) → alarm(0)

Timing has nothing to do with process status (natural timing method)! Ready, running, suspended (blocked, paused), terminated, zombie... no matter what state the process is in, alarm times.

Use the time command to view the program execution time (optimization)

  • time ./test

  • Conclusion: Actual execution time = system time + user time + waiting time 

  • time ./test > out (Input the results into out) Significantly improve performance

  • Conclusion: The bottleneck of program running is IO. Optimize the program and optimize IO first.

setitimer function

Set a timer (alarm clock). Can replace alarm function. Precision microsecond us, can realize periodic timing

int setitimer (int which, const struct itimerval *new_value, struct itimerval *old_value);    

        Success: 0; Failure: -1, set errno

        parameter:

                Parameter 1 which : specifies the timing method

                        ①Natural timing: ITIMER_REAL → 14) SIGLARM calculates natural time

                        ② Virtual space timing (user space): ITIMER_VIRTUAL → 26) SIGVTALRM only calculates the time the process occupies the CPU

                        ③ Runtime timing (user + kernel): ITIMER_PROF → 27) SIGPROF calculates the time occupied by the CPU and executing system calls

                Parameter 2: The structure sets the interval time and single time

                参数三: Returns the remaining time of the old alarm clock (outgoing parameter)

  • it_value: Parameters inside the structure : the time when the signal is first triggered
  • it_interval: Parameters inside the structure : used to set the time interval between two scheduled tasks (the time interval between the second and first time or the third and second time)

Guess you like

Origin blog.csdn.net/weixin_43200943/article/details/129831416