有一些api通常会有两个版本:mt-safe 和 mt unsafe. 例如:rand() 和rand_r(); token() 和token_r().
int rand(void);
int rand_r(unsigned int *seed);
char *strtok(char *s1, const char *s2);
char *strtok_r(char *s1, const char *s2, char **lasts);
后面有_r的是mt safe的。
为什么rand()和strtok()是mt unsafe呢?主要是函数里面有static变量,或者用到了全局变量。
以strtok()为例:
下面的代码根据指定的分隔符来遍历一个字符串。
for(token = strtok(strSrc, delimiter); token; token = strtok(NULL, delimiter))
{
}
每次调用strtok(), 该函数会记住下次遍历的起始位置。怎么记住?就要靠static变量,或者全局变量了。
这样就导致该函数是mt unsafe.
对于strtok_r(), 每次调用的时候,需要caller定义一个指针,将其地址作为参数传给char **lasts.目的也是要记住下次遍历的起始位置。不过,这个值得存储空间是有caller来指定的。所以就是mt safe。