码迷,mamicode.com
首页 > 编程语言 > 详细

可重入函数与线程安全问题

时间:2016-05-07 16:50:22      阅读:186      评论:0      收藏:0      [点我收藏+]

标签:寄存器   程序   检测   空间   用户   

线程安全函数

 确保线程安全: 
       要确保函数线程安全,主要需要考虑的是线程之间的共享变量。属于同一进程的不同线程会共享进程内存空间中的全局区和堆,而私有的线程空间则主要包括栈和寄存器。因此,对于同一进程的不同线程来说,每个线程的局部变量都是私有的,而全局变量、局部静态变量、分配于堆的变量都是共享的。在对这些共享变量进行访问时,如果要保证线程安全,则必须通过加锁的方式。 
线程不安全的后果: 
       线程不安全可能导致的后果是显而易见的——共享变量的值由于不同线程的访问,可能发生不可预料的变化,进而导致程序的错误,甚至崩溃。 

可重入函数概念: 

举个例子:主函数与信号处理函数共同调用一个同一个函数(在一张全局链表中头插一个节点),主函数先插入,操作过程分为两步,p->next=head;head=p;当执行完第一步操作后可能突然被中断,使进程从用户态切换到内核态,再次回到用户态时检测到有信号待处理,于是切换到用户态执行信号处理函数,而给函数中又执行了头插一个节点的操作,插入节点结束后又返回到内核态,在从内核态返回到主函数中调用插入函数的下边继续执行第二步,对于同一张链表,每次只能头插一个节点,结果只能插进去一个节点而另一个会被丢弃。

因此该插入函数被不同的控制流调用,有可能第一次调用还未返回前就再次进入该函数,因此就称该函数为可重入函数。

技术分享       
确保可重入: 
       要确保函数可重入,需满足以下几个条件: 
       1、不在函数内部使用静态或全局数据 
       2、不返回静态或全局数据,所有数据都由函数的调用者提供。 
       3、使用本地数据,或者通过制作全局数据的本地拷贝来保护全局数据。 
       4、不调用不可重入函数。

确保不可重入:

      1.调用了malloc或free,因为malloc也是用全局链表来管理堆的。

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

不可重入的后果: 
       不可重入的后果主要体现在象信号处理函数这样需要重入的情况中。如果信号处理函数中使用了不可重入的函数,则可能导致程序的错误甚至
崩溃。 

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

     1.可重入函数是线程安全函数的一种,其特点在于它们被多个线程调用时,不会引用任何共享数据,也就是不引用静态或全局变量。
     2.可重入函数通常要比不可重入的线程安全函数效率高一些,因为它们不需要同步操作。

     3.一个函数对于多个线程是可重入的,则这个函数是线程安全的。
    4.一个函数是线程安全的,但并不一定是可重入的。【使用互斥锁实现的线程安全】

可重入函数与线程安全问题

标签:寄存器   程序   检测   空间   用户   

原文地址:http://10541559.blog.51cto.com/10531559/1770993

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!