对比线程安全和可重入函数

来源:互联网 发布:华为mate8预装软件列表 编辑:程序博客网 时间:2024/06/05 06:39

1. 什么是线程安全,如何避免? 

       线程安全就是多线程访问时,采用了加锁机制,当一个线程访问该类的某个数据时,进行保护,其他线程不能进行访问直到该线程读取完,其他线程才可使用。不会出现数据不一致或者数据污染。

     如果你的代码所在的进程中有多个线程在同时运行,而这些线程可能会同时运行这段代码。如果每次运行结果和单线程运行的结果是一样的,而且其他的变量的值也和预期的是一样的,就是线程安全的。
     或者说:一个类或者程序所提供的接口对于线程来说是原子操作或者多个线程之间的切换不会导致该接口的执行结果存在二义性,也就是说我们不用考虑同步的问题。
     线程安全问题都是由全局变量及静态变量引起的。

     若每个线程中对全局变量、静态变量只有读操作,而无写操作,一般来说,这个全局变量是线程安全的;若有多个线程同时执行写操作,一般都需要考虑线程同步,否则的话就可能影响线程安全。

     对于多线程的程序,访问冲突的问题是很普遍的,解决的办法是引入互斥锁

2. 什么是可重入函数,有什么特点?

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

注意事项

      编写可重入函数时,若使用全局变量,则应通过关中断、信号量(即P、V操作)等手段对其加以保护。

      若对所使用的全局变量不加以保护,则此函数就不具有可重入性,即当多个进程调用此函数时,很有可能使有关全局变量变为不可知状态。

下面的函数多数是不可重入函数:

    (1)函数体内不能使用静态的数据结构;
    (2)函数体内调用了Malloc()或free();
    (3)函数体内调用了标准I/O函数。

编写不可重入函数:

    (1)不能在函数内部使用静态或全局数据
    (2)不能返回静态或全局数据,所有数据都有函数的调用者提供
    (3)使用本地数据、或通过制作全局数据的本地拷贝来保护全局数据。
    (4)如果必须访问全局变量,利用互斥机制来保护全变量。
    (5)不在可重入函数内部调用不可重入函数。
    (6)不调用malloc和free函数,因为malloc是用全局链表来管理堆的。
    (7)不调用了标准I/O函数很多都以不可重入的方式实现全局变量
最常见的就是在信号处理函数中不能使用不可重入函数。如果在信号处理中使用了不可重入函数,则可能导致程序出现错误甚至崩溃。

3.对比两者线程安全与可重入的区别与联系

       线程安全的根源就在于”共享数据”。所以不共享任何数据的函数(可重入函数)肯定是线程安全的。但是,即使有共享数据,线程安全还可以通过同步与互斥来保证,所以线程安全并不一定是可重入的。

原创粉丝点击