当前位置:网站首页>Reentrant function

Reentrant function

2022-04-23 20:46:00 baboon_ chen

One 、 Global variables are asynchronous IO What problems may be caused ?

The parent-child processes accumulate :

#include <stdio.h>
#include <signal.h>
#include <unistd.h>
#include <stdlib.h>

//  Parent-child processes pair n Add up 
//  every other 1 second , Send signals to each other to inform accumulation 
int n = 0, flag = 0;

void sys_err(char *str)
{
    
	perror(str);
	exit(EXIT_FAILURE);
}

void deal_sig_child(int signo)
{
    
	printf("I am child %d\t%d\n", getpid(), n);
	n += 2;
	flag = 1;	//  Count complete 
	//sleep(1);
}

void deal_sig_parent(int num)
{
    
	printf("I am parent %d\t%d\n", getpid(), n);
	n += 2;
	flag = 1;	//  Count complete 
	//sleep(1);
}

int main()
{
    
	pid_t pid;
	struct sigaction act;

	if ((pid = fork()) < 0)
	{
    
		sys_err("fork");
	}
	else if (pid > 0)
	{
    
		n = 1;
		sleep(1); //  Ensure that the action of sub process registration signal can be completed 
		act.sa_handler = deal_sig_parent;
		sigemptyset(&act.sa_mask);
		act.sa_flags = 0;
		sigaction(SIGUSR2, &act, NULL);	//  register SIGUSR2 Capture function 

		//  The parent process starts accumulating 
		deal_sig_parent(0);
		
		while(1)
		{
    
			// wait for signal
			if (flag == 1) 
			{
    
				kill(pid, SIGUSR1);
                  // ---------------- There may be a loss of CPU
				flag = 0;
			}
		}
	}
	else if (pid == 0)
	{
    
		n = 2;
		act.sa_handler = deal_sig_child;
		sigemptyset(&act.sa_mask);
		act.sa_flags = 0;
		sigaction(SIGUSR1, &act, NULL);	//  register SIGUSR1 Capture function 

		while(1)
		{
    
			// wait for signal
			if (flag == 1) 
			{
    
				kill(getppid(), SIGUSR2); //  Send to parent process SIGUSR2
				flag = 0;
			}
		}
	}

	return 0;
}

SIGUSR1: 10, User defined signals . That is, the programmer can define and use the signal in the program . The default action is to terminate the process .

SIGUSR2: 12, Another user-defined signal . That is, the programmer can define and use the signal in the program . The default action is to terminate the process .

   If you comment out two places in the code sleep(1), There is a problem :n After accumulating for a while , No more accumulation , The program enters the loop and waits . Here's why :

  1. Parent process call kill Send a signal to the child process , Notification start count .
  2. The parent process is executing flag=0 You may lose CPU, wait for CPU.
  3. And the child process count is complete , Will send a signal to the parent process .
  4. The parent process gets CPU after , Call the signal processing function first , take flag = 1;
  5. After the parent process has processed the signal , Restore to breakpoint to continue processing , perform flag = 0,flag The value of is overridden .
  6. At this time, the child process no longer sends signals to the parent process , Nor can the parent process send signals to the child process , The program is in a dead loop .

resolvent :

  1. Lock ;
  2. Don't use global variables , Make the signal processing function reentrant .

Two 、 What is a reentrant function ?

   When a function is called and executed ( The call has not ended yet ), Because a certain timing is repeatedly called , be called Reentrant . According to the method of function implementation, it is divided into Reentrant function and Non reentrant function Two kinds of .

1、 Reentrant function

int main()
{
    
    func(a) {
    
        ...
        func(a);
        ...
    }
}

int main()
{
    
    func(a);
    func(a);
}

//  If the top two main The results of function execution are consistent , said func(int a) Is a reentrant function .

   Recursive calls and successive calls , Consistent result , Is a reentrant function .

2、 Non reentrant function

 Insert picture description here


   obviously ,insert A function is a non reentrant function , Repeated calls to , Can lead to unexpected results . The reason is , It is the internal implementation of the function that uses global variables head.

3、 matters needing attention

  1. Define reentrant functions , A function cannot contain global variables and static Variable , Out of commission malloc、free.

  2. The signal capture function should be designed as a reentrant function .

  3. The reentrant functions that can be called by the signal handler can refer to man 7 signal.

  4. Most of the functions not included in the above list are non reentrant functions . The reason is :

    a) Using a static data structure

    b) Called malloc or free

    c) It's a standard. IO function

版权声明
本文为[baboon_ chen]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/04/202204210546350847.html