语言的运行库为了支持多线程特性,必须做出一些改进。一种改进的办法就是修改所有的线程不安全的函数的参数列表,改成某种线程安全的版本。比如MSVC的CRT就提供了线程安全版本的strtok()函数:strtok_s,它们的原型如下:
char *strtok(char *strToken, const char *strDelimit );
char *strtok_s( char *strToken, const char *strDelimit, char **context);
改进后的strtok_s增加了一个参数,这个参数context是由调用者提供一个char*指针,strtok_s将每次调用后的字符串位置保存在这个指针中。而之前版本的strtok函数会将这个位置保存在一个函数内部的静态局部变量中,如果有多个线程同时调用这个函数,有可能出现冲突。与MSVC CRT类似,Glibc也提供了一个线程安全版本的strtok()叫做strtok_r()。
但是很多时候改变标准库函数的做法是不可行的。标准库之所以称之为“标准”,就是它具有一定的权威性和稳定性,不能随意更改。如果随意更改,那么所有遵循 该标准的程序都需要重新进行修改,这个“标准”是不是值得遵循就有待商榷了。所以更好的做法是不改变任何标准库函数的原型,只是对标准库的实现进行一些改 进,使得它能够在多线程的环境下也能够顺利运行,做到向后兼容。