- strtok是字符串分割函数
- strtok_r是strtok的线程安全版本
(一)问题:多线程中strtok时出现异常情况
- 代码:
#include <string.h>
#include <stdio.h>
#include <pthread.h>
void* pthread_fun(void* arg)
{
char bbuff[] = {
"a b c d e"};
char* p = strtok(bbuff, " ");
while(p != NULL)
{
printf("%s\n", p);
p = strtok(NULL, " ");
}
}
int main()
{
char abuff[] = {
"A B C D E"};
pthread_t id;
pthread_create(&id, NULL, pthread_fun, NULL);
char* s = strtok(abuff, " ");
while(s != NULL)
{
printf("%s\n", s);
s = strtok(NULL, " ");
}
pthread_join(id, NULL);
return 0;
}
-
结果:
-
原因分析:原因在于strtok函数内部定义了一个静态指针变量 lasts用来记录上次切割的地址,在多线程中共享静态变量的缘故,出现了混乱。
(二)解决方案:使用strtok_r
代码:
#include <string.h>
#include <stdio.h>
#include <pthread.h>
void* pthread_fun(void* arg)
{
char bbuff[] = {
"a b c d e"};
char* psave = NULL;
char* p = strtok_r(bbuff, " ", &psave);
while(p != NULL)
{
printf("%s\n", p);
p = strtok_r(NULL, " ", &psave);
}
}
int main()
{
pthread_t id;
pthread_create(&id, NULL, pthread_fun, NULL);
char abuff[] = {
"A B C D E"};
char* ssave = NULL;
char* s = strtok_r(abuff, " ", &ssave);
while(s != NULL)
{
printf("%s\n", s);
s = strtok_r(NULL, " ", &ssave);
}
pthread_join(id, NULL);
return 0;
}
- 结果: