Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

What are the differences between reentrant and non-reentrant functions

2025-03-29 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/02 Report--

This article introduces the relevant knowledge of "what is the difference between reentrant and non-reentrant functions". In the operation of actual cases, many people will encounter such a dilemma. Next, let the editor lead you to learn how to deal with these situations. I hope you can read it carefully and be able to achieve something!

What are reentrant functions and non-reentrant functions?

Reentrant and non-reentrant functions are mainly used in multitasking environments. A reentrant function is simply a function that can be interrupted, that is, it can be interrupted at any time when the function is executed, and it can be transferred to the OS schedule to execute another piece of code without any error when returning to control.

The non-reentrant function may have problems if it is interrupted because it uses some system resources, such as global variable area, interrupt vector table and so on. This kind of function cannot be run in a multitasking environment.

Can also be understood this way, reentry means repeated entry, first of all, it means that the function can be interrupted, and secondly means that it in addition to using its own stack variables do not rely on any environment (including static), such a function is purecode (pure code) reentrant, you can allow multiple copies of the function in the run, because they use a separate stack, so will not interfere with each other.

If you do need to access global variables (including static), be sure to implement mutexes. Reentrant functions are very important in parallel running environments, but there is generally a performance cost for accessing global variables.

Second, the shortcomings of non-reentrant functions.

When writing reentrant functions, if global variables are used, they should be protected by turning off interrupts, semaphores (that is, P, V operations) and other means.

Note: if the global variables used are not protected, this function is not reentrant, that is, when multiple processes call this function, it is likely to make the relevant global variables unknowable.

Example: suppose Exam is an int global variable, and the function Squre_Exam returns the square of Exam. Then the following functions are not reentrant.

Unsignedint example (int para) {unsignedint temp; Exam= para; / / (* *) temp = Square_Exam (); return temp;}

If this function is called by multiple processes, the result may be unknown, because just after the (* *) statement is executed, another process using this function may be activated, so when the newly activated process executes to this function, the Exam will be assigned a different paraple.So, when the control returns to temp=Square_Exam (), the calculated temp is probably not the expected result. This function should be improved as follows:

Unsignedint example (int para) {unsignedint temp; [apply for semaphore operation] / / (1) Exam= para; temp = Square_Exam (); [release semaphore operation] return temp;}

If the semaphore is not available, another process is in the process of assigning a value to the Exam and calculating its square (that is, the signal is being used), and the process must wait for it to release the signal before continuing. If the signal is requested, it can continue, but other processes must wait for the semaphore to be released by the process before using this signal again.

Third, the method to ensure the reentrancy of the function.

When writing functions, try to use local variables (such as registers, variables in the stack), and protect the global variables to be used (such as turning off interrupts, semaphores, etc.). In this way, the constructed function must be a reentrant function.

In the design of real-time system, it often occurs that multiple tasks call the same function. If this function is unfortunately designed to be a non-reentrant function, different tasks may modify the data of other tasks calling this function when calling this function, resulting in unpredictable consequences. Non-reentrant functions are regarded as unsafe functions in real-time system design.

Most functions that meet the following conditions are non-reentrant:

The static data structure is used in the function body.

The malloc () or free () function is called inside the function body

The standard Istroke O function is called inside the function body.

The following examples are given to illustrate.

a. Reentrant function

Void strcpy (char*lpszDest, char*lpszSrc) {while (* lpszDest++=*lpszSrc++); * dest=0;}

b. Non-reentrant function 1

CharcTemp;// global variable voidSwapChar1 (char*lpcX, char*lpcY) {cTemp=*lpcX; * lpcX=*lpcY; lpcY=cTemp;// accessed the global variable}

c. Non-reentrant function 2

VoidSwapChar2 (char*lpcX,char*lpcY) {staticchar cTemp;// static local variable cTemp = * lpcX; * lpcX = * lpcY; lpcY = cTemp;// uses static local variable}

Question1: how to write reentrant functions?

Answer: do not access those global variables in the function body, do not use static local variables, insist on using only local variables, the written function will be reentrant. If you must access global variables, remember to protect global variables with mutex semaphores.

Question 2: how to rewrite a non-reentrant function into a reentrant function?

Answer: the only way to make a non-reentrant function reentrant is to rewrite it with reentrant rules. In fact, it is very simple, as long as you follow a few rules that are easy to understand, then the written function is reentrant.

Do not use global variables. Because other code is likely to override the values of these variables.

When interacting with the hardware, remember to perform operations like disinterrupt (), which is to turn off the hardware interrupt. After completing the interaction, remember to turn on the interrupt, which in some series is called "enter / exit the core".

You cannot call any other non-reentrant function.

Use the stack carefully. It's best to OSENTERKERNAL before using it.

Stack operations involve memory allocation, and a little carelessness can lead to data overwriting other tasks, so use stacks with caution! Better not use it! Many hacker programs take advantage of this so that the system can execute illegal code and easily gain control of the system. There are also some rules, in short, always remember one sentence: make sure the interrupt is safe!

Example question: once designed a function that was reminded of bug during code review, because this function is non-reentrant, why?

Unsignedint sum_int (unsignedint base) {unsignedint index; staticunsignedint sum = 0; / / Note, it is the static type for (index = 1; index)

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report