Linux 可重入函数与线程安全

来源:互联网 发布:遗传算法java实现 编辑:程序博客网 时间:2024/04/28 18:12

一、 可重入函数
简单来说,就是可以被中断的函数。当函数正在运行时,被系统切出去,执行其他线程,当系统再一次切回这个函数时,函数状态,上下文等都没有改变,即这个函数是可重入函数,反之则不是。

满足可重入函数的条件:
1、不使用全局变量或静态变量;
2、不使用用malloc或者new开辟出的空间;
3、不调用不可重入函数;
4、不返回静态或全局数据,所有数据都有函数的调用者提供;
5、使用本地数据,或者通过制作全局数据的本地拷贝来保护全局数据;

不可重入函数符合以下条件:
1、调用了malloc/free函数,因为malloc函数是用全局链表来管理堆的。
2、调用了标准I/O库函数,标准I/O库的很多实现都以不可重入的方式使用全局数据结构。
3、可重入体内使用了静态的数据结构。

综上,一个可重入函数要么只使用自己栈空间内值传递的数据或者引用传递(指针),要么使用加了保护的临界资源中的数据。
二、线程安全

一个函数被称为线程安全的(thread-safe),当且仅当被多个并发进程反复调用时,它会一直产生正确的结果。反之,如果一个函数不是线程安全的,我们就说它是线程不安全的(thread-unsafe)。

所以,有这么四类函数称为线程不安全的:
1、不保护共享变量的函数;
2、函数状态随着调用改变的函数;
3、返回指向静态变量指针的函数;
4、调用线程不安全函数的函数;

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

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

1、线程安全是在多线程情况下引发的,而可重入函数可以在只有一个线程的情况下发生。

2、线程安全不一定是可重入的,而可重入函数则一定是线程安全的。

3、如果一个函数有全局变量,则这个函数既不是线程安全也不是可重入的。

4、如果一个函数当中的数据全身自身栈空间的,则这个函数即使线程安全也是可重入的。

5、如果将对临界资源的访问加锁,则这个函数是线程安全的;但如果重入函数的话加锁还未释放,则会产生死锁,因此不能重入。

6、线程安全函数能够使不同的线程访问同一块地址空间,而可重入函数要求不同的执行流对数据的操作不影响结果,使结果是相同的。

即 可重入与线程安全的关系是充分不必要的

0 0
原创粉丝点击