线程安全函数安全
概念:
线程安全的概念比较直观。通常说来,一个函数被称为线程安全的,当且仅当被多个并发线程反复调用时,它会一直产生正确的结果。
确保线程安全:
要确保函数线程安全,主要须要考虑的是线程之间的共享变量。属于同一进程的不一样线程会共享进程内存空间中的全局区和堆,而私有的线程空间则主要包括栈和寄存器。所以,对于同一进程的不一样线程来讲,每一个线程的局部变量都是私有的,而全局变量、局部静态变量、分配于堆的变量都是共享的。在对这些共享变量进行访问时,若是要保证线程安全,则必须经过加锁的方式。
线程不安全的后果:
线程不安全可能致使的后果是显而易见的——共享变量的值因为不一样线程的访问,可能发生不可预料的变化,进而致使程序的错误,甚至崩溃。 多线程
可重入函数
概念:
在多线程或有异常控制流的状况下,当某个函数运行到中途时,控制流(也就是当前指令序列)就有可能被打断而去执行另外一个函数.而"另外一个函数"颇有多是它自己.,若是在这种状况下不会出现问题,好比说数据或状态不会被破坏,行为肯定。那么这个函数就被称作"可重入"的.函数是可重入(reentrant)的,是指对于相同的(而且合法的)函数参数(包括无参函数的状况),屡次重复调用此函数产生的行为是可预期的,即函数的行为一致,或者结果相同。不能保证这一点的函数称为不可重入(non-reentrant)函数。并发
确保可重入:
要确保函数可重入,需知足如下几个条件:
一、不在函数内部使用静态或全局数据
二、不返回静态或全局数据,全部数据都由函数的调用者提供。
三、使用本地数据,或者经过制做全局数据的本地拷贝来保护全局数据。
四、不调用不可重入函数。
不可重入的后果:
不可重入的后果主要体如今象信号处理函数这样须要重入的状况中。若是信号处理函数中使用了不可重入的函数,则可能致使程序的错误甚至崩溃。
ide
可重入与线程安全函数
可重入与线程安全并不等同。通常说来,可重入的函数必定是线程安全的,但反过来不必定成立。它们的关系可用下图来表示:spa
咱们能够采用下面的变化过程来进一步说明上图:
- 若是一个函数中用到了全局或静态变量,那么它不是线程安全的,也不是可重入的;
- 若是咱们对它加以改进,在访问全局或静态变量时使用互斥量或信号量等方式加锁,则可使它变成线程安全的,但此时它仍然是不可重入的,由于一般加锁方式是针对不一样线程的访问,而对同一线程可能出现问题;
- 若是将函数中的全局或静态变量去掉,改为函数参数等其余形式,则有可能使函数变成既线程安全,又可重入。
好比:strtok函数是既不可重入的,也不是线程安全的;加锁的strtok不是可重入的,但线程安全;而strtok_r既是可重入的,也是线程安全的。线程