可重入函数和线程安全

1、可重入函数html

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

                    wKiom1cxR6WjWsAdAADbeVhDlIk346.jpg如上图:安全

    main函数调用insert函数向一个链表head中插入节点node1,插入操做分为两步,刚作完第一步的 时候,由于硬件中断使进程切换到内核,再次回用户态以前检查到有信号待处理,因而切换到sighandler函数,sighandler也调用insert函数向同一个链表head中插入节点node2,插入操做的两步都作完以后从ighandler返回内核态,再次回到用户态就从main函数调用的insert函数中继续往下执行,先前作第一步以后被打断,如今继续作完第二步。结果是,main函数和sighandler前后向链表中插入两个节点,而最后只有一个节点真正插入链表中了。这就出现了泄漏。像上例这样,insert函数被不一样的控制流程调用,有可能在第一次调用还没返回时就再次进入该函数,这称为重入,insert函数访问一个全局链表,有可能由于重入而形成错乱,像这样的函数称为不可重入函数,反之,若是一个函数只访问本身的局部变量或参数,则称为可重入(Reentrant) 函数数据结构

   一、 若是一个函数符合如下条件之一则是不可重入的多线程

    ①、调用了malloc或free,由于malloc也是用全局链表来管理堆的。ide

    ②、调用了标准I/O库函数。标准I/O库的不少实现都以不可重入的方式使用全局数据结构。函数

2、线程安全spa

  若是代码所在的进程中有多个线程在同时运行,而这些线程可能会同时运行这段代码。若是每次运行结果和单线程运行的结果是同样的,并且其余的变量的值也和预期的是同样的,就是线程安全的。或者说:一个类或者程序所提供的接口对于线程来讲是原子操做或者多个线程之间的切换不会致使该接口的执行结果存在二义性,       线程

线程安全问题都是由全局变量及静态变量引发的。若每一个线程中对全局变量、静态变量只有读操做,而无写操做,通常来讲,这个全局变量是线程安全的;如有多个线程同时执行写操做,通常都须要考虑线程同步,不然的话就可能影响线程安全。产生线程安全的本质在于:线程共享和执行流发生了干扰。要确保线程安全,线程在对共享变量进行访问时必须以加锁的方式。orm

      好比一个 ArrayList 类,在添加一个元素的时候,它可能会有两步来完成:1. 在 Items[Size] 的位置存放此元素;2. 增大 Size 的值。

            在单线程运行的状况下,若是 Size = 0,添加一个元素后,此元素在位置 0,并且 Size=1;而若是是在多线程状况下,好比有两个线程,线程 A 先将元素存放在位置 0。可是此时 CPU 调度线程A暂停,线程 B 获得运行的机会。线程B也向此 ArrayList 添加元素,由于此时 Size 仍然等于 0 (注意,咱们假设的是添加一个元素是要两个步骤哦,而线程A仅仅完成了步骤1),因此线程B也将元素存放在位置0。而后线程A和线程B都继续运行,都增长 Size 的值。那好,咱们来看看 ArrayList 的状况,元素实际上只有一个,存放在位置 0,而 Size 却等于 2。这就是“线程不安全”了。


3、可重入函数与线程安全的联系与区别

    一、可重入函数必定是线程安全的,单线程安全不必定是可重入的