pthread的TLS(THREAD LOCAL STORAGE)
来源:互联网 发布:淘宝详情分割线 编辑:程序博客网 时间:2024/05/22 02:24
TLS全称为Thread Local Storage,是系统为解决一个进程中多个线程同时访问全局变量而提供的机制,保证数据的完整性与正确性,也可以称为 Thread Specific Data ,即表面上看起来这是一个全局变量,所有线程都可以使用它,而它的值在每一个线程中又是单独存储的,在linux中主要有pthread_key实现。
pthread _key接口介绍
int pthread_key_create(pthread_key_t *key, void (*destr_function) (void *))
该函数从TSD池中分配一项,将其值赋给key供以后访问使用。如果destr_function不为空,在线程退出(pthread_exit())时将以key所关联的数据为参数调用destr_function(),以释放分配的缓冲区。
不论哪个线程调用pthread_key_create(),所创建的key都是所有线程可访问的,但各个线程可根据自己的需要往key中填入不同的值,这就相当于提供了一个同名而不同值的全局变量。
注销一个TSD采用如下API:
int pthread_key_delete(pthread_key_t key)
这个函数并不检查当前是否有线程正使用该TSD,也不会调用清理函数(destr_function),而只是将TSD释放以供下一次调用pthread_key_create()使用。在LinuxThreads中,它还会将与之相关的线程数据项设为NULL(见"访问")。
TSD的读写都通过专门的Posix Thread函数进行,其API定义如下:
int pthread_setspecific(pthread_key_t key, const void *pointer)
void * pthread_getspecific(pthread_key_t key)
写入(pthread_setspecific())时,将pointer的值(不是所指的内容)与key相关联,而相应的读出函数则将与key相关联的数据读出来。数据类型都设为void *,因此可以指向任何类型的数据。
例子:
#include<stdio.h>#include<stdlib.h>#include<unistd.h>#include<jni.h>#include<signal.h>#include<sys/time.h>#include<pthread.h> #include <fcntl.h>#include <sys/types.h>#include <sys/epoll.h>#include <limits.h>#include<android/log.h>#define LOGI(...) ((void)__android_log_print(ANDROID_LOG_INFO, "native-activity", __VA_ARGS__))#define LOGW(...) ((void)__android_log_print(ANDROID_LOG_WARN, "native-activity", __VA_ARGS__))#define LOGE(...) ((void)__android_log_print(ANDROID_LOG_ERROR, "native-activity", __VA_ARGS__))#ifndef NELEM# define NELEM(x) ((int) (sizeof(x) / sizeof((x)[0])))#endifstatic char CLASS_NAME[] = "com/sailor/Pthread";static pthread_key_t gTLSKey = 0; // thread local storagepthread_once_t initonce = PTHREAD_ONCE_INIT;static void threadDestructor(void *st){// 线程退出,销毁数据 LOGE("Destroy pthread key");}static void *init_routine(void *st){sleep(1);LOGE("poll_once");int tid = pthread_self();LOGE("poll_once Thread:%d", tid);pthread_setspecific(gTLSKey, (void *)1);LOGE("poll_once Thread:%d return %d", tid, (int)pthread_getspecific(gTLSKey));}static void *child1(void *arg1){int error;LOGE("child1");int tid = pthread_self();LOGE("child1 Thread:%d", tid);pthread_setspecific(gTLSKey, (void *)tid);LOGE("child1 Thread:%d return %d", tid, (int)pthread_getspecific(gTLSKey));sleep(5);LOGE("child1 Thread:%d return %d", tid, (int)pthread_getspecific(gTLSKey));}static int CreateThread(){int result = pthread_key_create(&gTLSKey, threadDestructor);if(result != 0){LOGE("Could not allocate TLS key.");}return result;}static void Start(){int tid;int error;pthread_create(&tid, NULL, child1, NULL);pthread_create(&tid, NULL, init_routine, NULL);// 只执行一次,下回调用不会执行init_routine /* if (error = pthread_once(&initonce, init_routine)) { LOGE("pthread_once: %d\r\n",error); }else{LOGE("poll_once pthread start");}*/}static int DestroyThread(){pthread_key_delete(gTLSKey);}static JNINativeMethod mehods[] = {{ "createThread", "()I", (void *) CreateThread },{ "destroyThread", "()I", (void *) DestroyThread },{ "start", "()V", (void *) Start }};static int registerNativeMethods(JNIEnv *env, const char* className, const JNINativeMethod* methods, int numMethods){ int rc; jclass clazz; clazz = (*env)->FindClass(env, className); if (clazz == NULL) { LOGE("Native registration unable to find class '%s'\n", className); return -1; } if (rc = ((*env)->RegisterNatives(env, clazz, methods, numMethods)) < 0) { LOGE("RegisterNatives failed for '%s' %d\n", className, rc); return -1; } return 0;}static int register_jni(JNIEnv *env){return registerNativeMethods(env, CLASS_NAME, mehods, NELEM(mehods));}JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved){ JNIEnv* env = NULL; jint result = -1; //获取JNI版本 if ((*vm)->GetEnv(vm, (void**)&env, JNI_VERSION_1_4) != JNI_OK) { LOGE("GetEnv failed!"); return result; } if (register_jni(env) < 0) {LOGE("register method failed!"); return result; } return JNI_VERSION_1_4;}
java类:
package com.sailor;import android.util.Log;public class Pthread {static {// 加载动态库System.loadLibrary("JNIPthread");}public native int createThread();public native void start();public native int destroyThread();}
public void startTLS(View view){pthread = new Pthread();Log.d("jacklam", "create thread");pthread.createThread();Log.d("jacklam", "start thread");pthread.start();/*Log.d("jacklam", "destroy thread");*//*pthread.destroyThread();*/}
结果:
10-15 11:36:23.348: D/jacklam(7868): create thread10-15 11:36:23.348: D/jacklam(7868): start thread10-15 11:36:23.348: E/native-activity(7868): child110-15 11:36:23.348: E/native-activity(7868): child1 Thread:2399354410-15 11:36:23.348: E/native-activity(7868): child1 Thread:23993544 return 2399354410-15 11:36:24.359: E/native-activity(7868): poll_once10-15 11:36:24.359: E/native-activity(7868): poll_once Thread:2311934410-15 11:36:24.359: E/native-activity(7868): poll_once Thread:23119344 return 110-15 11:36:24.359: E/native-activity(7868): Destroy pthread key10-15 11:36:28.353: E/native-activity(7868): child1 Thread:23993544 return 2399354410-15 11:36:28.353: E/native-activity(7868): Destroy pthread key
0 0
- pthread的TLS(THREAD LOCAL STORAGE)
- TLS (Thread local storage)
- Thread-Local Storage(TLS)
- TLS:Thread Local Storage
- TLS:Thread Local Storage
- Thread-Local Storage: TLS
- Thread Local Storage(TLS)
- Thread Local Storage (TLS)
- TLS(Thread Local Storage)入门
- 线程的局部存储tls (thread local storage)
- 线程本地存储(Thread Local Storage, TLS)
- 为什么需要TLS(Thread Local Storage)?
- 线程局部存储TLS(thread local storage)
- [并发并行]_[C/C++]_[使用线程本地存储Thread Local Storage(TLS)-win32线程和pthread线程比较]
- windows下llvm的Thread-local-Storage(TLS)的问题
- 线程本地存储TLS(Thread Local Storage)的原理和实现——分类和原理
- 线程本地存储TLS(Thread Local Storage)的原理和实现——分类和原理
- 线程本地存储TLS(Thread Local Storage)的原理和实现——分类和原理
- UI_GestureRecognizer_手势识别器
- PEP 0263 -- Defining Python Source Code Encodings
- Oracle Redo Log File调整大小
- LayoutInflater的inflate函数用法详解
- HTML5移动开发(1)——HTML介绍
- pthread的TLS(THREAD LOCAL STORAGE)
- stcc
- oracle----sqlldr用法
- 从需求到实现的第一步,用例图
- linux ext4文件系统
- WindowManager.LayoutParams经常会用到的变量
- 关于委托
- C语言里全局变量管理
- LayoutInflater作用及使用