400 028 6601

建站动态

根据您的个性需求进行定制 先人一步 抢占小程序红利时代

如何理解可重入函数

本篇内容介绍了“如何理解可重入函数”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!

创新互联建站-成都网站建设公司,专注网站建设、网站制作、网站营销推广,域名注册网站空间,网站托管、服务器托管有关企业网站制作方案、改版、费用等问题,请联系创新互联建站

 1 前言

最近在公司维护的项目中碰到一个解决了定位很久的 bug , bug 找到的时候发现犯了很低级的错误——在中断处理函数中调用了 printf  函数,因为中断处理函数的调用了不可重入函数,导致中断丢失和系统位置错误,这里直接导致嵌入式 linux  系统应用进程中的所有线程停掉,进而导致看门狗进程得不到喂狗,设备重启。

就以上三个问题展开小短文:

2 什么是不可重入函数?

可重入函数主要用于多任务环境中,一个可重入的函数简单来说就是可以被中断的函数,也就是说,可以在这个函数执行的任何时刻中断它,转入 OS  调度下去执行另外一段代码,而返回控制时不会出现什么错误;而不可重入的函数由于使用了一些系统资源,比如全局变量区,中断向量表等,所以它如果被中断的话,可能会出现问题,这类函数是不能运行在多任务环境下的。

满足下列条件的函数多数是不可重入的:

A. 可重入函数

void strcpy(char *lpszDest, char *lpszSrc)  {     while(*lpszDest++=*lpszSrc++);///< 使用的局部变量     *dest=0; }

B. 不可重入函数1

char cTemp;    ///< 全局变量 void SwapChar1(char *lpcX, char *lpcY)  {     cTemp=*lpcX;     *lpcX=*lpcY;     lpcY=cTemp;   ///< 访问了全局变量 }

C. 不可重入函数2

void SwapChar2(char *lpcX,char *lpcY) {     static char cTemp;  ///< 静态局部变量     cTemp=*lpcX;     *lpcX=*lpcY;     lpcY=cTemp;   ///< 使用了静态局部变量 }

3 为什么中断处理函数不能直接调用不可重入函数?

在多任务系统下,中断可能在任务执行的任何时间发生;如果一个函数的执行期间被中断后,到重新恢复到断点进行执行的过程中,函数所依赖的环境没有发生改变,那么这个函数就是可重入的,否则就不可重入。

在中断前后不都要保存和恢复上下文吗,怎么会出现函数所依赖的环境发生改变了呢?我们知道中断时确实保存一些上下文,但是仅限于返回地址,cpu  寄存器等之类的少量上下文,而函数内部使用的诸如全局或静态变量,buffer  等并不在保护之列,所以如果这些值在函数被中断期间发生了改变,那么当函数回到断点继续执行时,其结果就不可预料了。

在中断处理函数中调用有互斥锁保护的全局变量,如果恰好该变量正在被另一个线程调用,会导致中断处理函数不能及时返回,导致中断丢失等严重问题。

并且在多线程环境中使用,在没有加锁的情况下,对同一段内存块进行并发读写,就会造成 segmentfault/coredump 之类的问题。

总而言之,中断处理函数做的事情越简单越好。

4 如何写出可重入的函数?

“如何理解可重入函数”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注创新互联网站,小编将为大家输出更多高质量的实用文章!


新闻名称:如何理解可重入函数
转载注明:http://mbwzsj.com/article/jccdhe.html

其他资讯

让你的专属顾问为你服务