如何选择靠谱的网站建设大数据培训
线程安全:在多线程运行的时候,不论线程的调度顺序怎样,最终的结果都是 一样的、正确的,这个线程就是安全的。
保证线程安全的要求:
1. 对线程同步,保证同一时刻只有一个线程访问临界资源。
2.在多线程中使用线程安全的函数(可重入函数)。
线程安全的函数:一个函数能被多个线程同时调用且不发生竟态条件。
不是线程安全的例子:
主线程分割字符串1 2 3 4 5 6
另一个线程分割字符串a b c d e f
#include<stdio.h>
#include<unistd.h>
#include<string.h>
#include<stdlib.h>
#include<pthread.h>void* fun(void*arg)
{char buff[128] = "a b c d e f";char*s = strtok(buff," ");while(s!=NULL){printf("fun =%s\n",s);sleep(1);s = strtok(NULL," ");}
}
int main()
{pthread_t id;pthread_create(&id,NULL,fun,NULL);char arr[128] = "1 2 3 4 5 6";char*p = strtok(arr," ");while(p!=NULL){printf("main p = %s\n",p);sleep(1);p = strtok(NULL," ");}
}
结果并没有输出main p = 2 3 4 5 6 ,这是因为多线程静态变量只有一份,无法分别记录信息,分割的东西会被覆盖,strtok方法中有静态变量记录分割后指向。
char *__cdecl strtok(char *_String, const char *_Delimiter)
而使用strtok_s()可以保证线程安全
strtok_s()函数的原型如下:
char *__cdecl strtok_s(char *_String, const char *_Delimiter, char **_Context)
_Context参数相当于strtok()函数中内部定义的静态SAVE_PTR指针,用来传递对字符串_String的处理进行到了哪里。
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <pthread.h>void* fun(void *arg)
{char buff[128] = "a b c d e f";char * ptr = NULL;char * s = strtok_r(buff," ",&ptr);while( s != NULL ){printf("fun s=%s\n",s);sleep(1);s = strtok_r(NULL," ",&ptr);}
}
int main()
{pthread_t id;pthread_create(&id,NULL,fun,NULL);char arr[128] = "1 2 3 4 5 6";char * ptr = NULL;char * p = strtok_r(arr," ",&ptr);while( p != NULL ){printf("main p=%s\n",p);sleep(1);p = strtok_r(NULL," ",&ptr);}pthread_join(id,NULL);exit(0);
}
结果:分割互不干扰
所以使用的函数有静态变量时需要使用其改进函数,保证线程安全。