转: 函数的线程安全和可重入

摘自:
http://liuaigui.blog.sohu.com/86494742.html

线程安全的(Thread-Safe):如果一个函数在同一时刻可以被多个线程安全地调用,就称该函数是线程安全的。线程安全函数解决多个线程调用函数时访问共享资源的冲突问题。

可重入(Reentrant):函数可以由多于一个线程并发使用,而不必担心数据错误。可重入函数可以在任意时刻被中断,稍后再继续运行,不会丢失数据。可重入性解决函数运行结果的确定性和可重复性。可重入函数编写规范为:
1、不在函数内部使用静态或全局数据 
2、不返回静态或全局数据,所有数据都由函数的调用者提供。 
3、使用本地数据,或者通过制作全局数据的本地拷贝来保护全局数据。
4、如果必须访问全局变量,利用互斥机制来保护全局变量。
5、不调用不可重入函数。

两者之间的关系:
1、一个函数对于多个线程是可重入的,则这个函数是线程安全的。
2、一个函数是线程安全的,但并不一定是可重入的。
3、可重入性要强于线程安全性。

比如:strtok函数是既不可重入的,也不是线程安全的。加锁的strtok不是可重入的,但线程安全。而strtok_r既是可重入的,也是线程安全的

之所以会去查这个问题,是在考试中遇到过考strtok这个问题是否可用于多线程。自己从使用的角度上感觉不安全,但是究其原因却不是很明白。查了一下,居然涉及到函数的线程安全。

在另一篇博文中,是这样解释的:
strtok不是一个线程安全的函数。因为根据其定义,它必须使用内部静态变量来记录字符串中下一个需要解析的标记的当前位置。但是,由于指示这个位置的变量只有一个,那么,在同一个程序中出现多个解析不同字符串的strtok调用时,各自的字符串的解析就会互相干扰。(摘自: http://hi.baidu.com/pigfanfan/blog/item/72816c958d63e743d1135ebf.html

怎么避免呢?
我们可以利用另一个函数:strtok_r,这个是一个线程安全的函数——strtok_r,以此来代替strtok。

你可能感兴趣的:(转: 函数的线程安全和可重入)