zoukankan      html  css  js  c++  java
  • 不可重入函数

    1.malloc,free, printf均是不可重入函数(意味不能在中断函数或信号处理函数同时调用),但是线程安全函数(意味它可以被多个线程调用)
    2.函数有static变量或者全局变量,则该函数是不可重入函数

    满足下面条件之一的多数是不可重入函数:

    (1)使用了静态数据结构或者全局变量;

    (2)调用了malloc或free;

    (3)调用了标准I/O函数;标准io库很多实现都以不可重入的方式使用全局数据结构。

    (4)进行了浮点运算.许多的处理器/编译器中,浮点一般都是不可重入的 (浮点运算大多使用协处理器或者软件模拟来实现。

    (5)调用printf。

    mallo函数和printf函数实现

    1.引用了全局变量 --- printf引用全局stdout, malloc,free会引用全局的内存分配表

    2.调用了semtake --- 在VxWorks源代码的函数memPartAlignedAlloc内存在这样一行代码semTake (&partId->sem, WAIT_FOREVER);它通过获取分区锁来保证内存申请操作的线程互斥,因此,在ISR内调用malloc会导致OS重复调用调度器函数reschedule出现中断重入。printf内部也包含了semTake操作,中断服务程序中不能有阻塞操作。

    可重入和线程安全(Thread-Safe)是两个不同的概念:可重入函数一定是线程安全的;线程安全的函数可能是重入的,也可能是不重入的;线程不安全的函数一定是不可重入的。

    rentrant函数与是不是多线程无关,如果是reentrant函数,那么要求即使是同一个进程(或线程)同时多次进入该函数时,该函数仍能够正确的运作.

    该要求还蕴含着,如果是在多线程环境中,不同的两个线程同时进入该函数时,该函数也能够正确的运作.

    thread safe函数是与多线程有关的,它只是要求不同的两个线程同时对该函数的调用在逻辑上是正确的.

    不可重入的非法调用例子:

    定义一个每微妙触发的定时器,触发时产生alarm信号,在信号处理函数中调用malloc/free,程序主循环也调用malloc/free--这样程序就死锁了。

    两者不等价。可重入更严格。如果一个函数的实现使用了全局或者静态变量,那么这个函数既不是可重入的,也不是线程安全的。如果放宽条件,这个函数仍然用到了全局或者静态变量,但是在访问这些变量时,通过加锁来保证互斥访问,那么这个函数就可以变成线程安全的函数。但它此时仍然是不可重入的,因为通常加锁是针对不同线程的访问,对同一线程可能出现问题(发生信号软中断,signal handler中恰巧也执行了该函数)。那么如果把函数中的全局和静态变量都干掉,并保证在该函数中也不调用不可重入的函数,那么这个函数可以做到既是线程安全的,也是可重入的。综上,可重入函数一般都是线程安全的,线程安全的不一定是可重入的

    作者:Acjx
    链接:https://www.zhihu.com/question/21526405/answer/56823146
    来源:知乎
    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

  • 相关阅读:
    js遍历多层对象的键值对
    JS HEX十六进制与RGB, HSL颜色的相互转换【转】
    TortoiseSVN打分支、合并分支、切换分支【转】
    grid.containLabel
    安装谷歌vue-devtools调试插件
    使用Echarts遇到的问题
    理解js编程中函数的副作用
    git 镜像下载和安装
    欢迎来到博客园的世界
    c#制作一个屏幕保护程序
  • 原文地址:https://www.cnblogs.com/wanmeishenghuo/p/9215946.html
Copyright © 2011-2022 走看看