头文件位置:bionic/libc/include/
源码实现位置:bionic/libc/bionic/
https://blog.csdn.net/weixin_46935110/article/details/130792477
https://blog.csdn.net/Lid_23/article/details/132036106
https://blog.csdn.net/qq_34888036/article/details/133960234
https://blog.csdn.net/swartz_lubel/article/details/77150949
目录
特性说明(****)
不论哪个线程调用了 pthread_key_create(),所创建的 key 都是所有线程可以访问的,但各个线程可以根据自己的需要往 key 中填入不同的值,相当于提供了一个同名而不同值的全局变量(这个全局变量相对于拥有这个变量的线程来说)。
具体类讲解
pthread_types.h
typedef int pthread_key_t;
typedef long pthread_t
pthread_key.cpp
-
pthread_key_create方法
124 int pthread_key_create(pthread_key_t* key, void (*key_destructor)(void*)) { 125 for (size_t i = 0; i < BIONIC_PTHREAD_KEY_COUNT; ++i) { 126 uintptr_t seq = atomic_load_explicit(&key_map[i].seq, memory_order_relaxed); 127 while (!SeqOfKeyInUse(seq)) { 128 if (atomic_compare_exchange_weak(&key_map[i].seq, &seq, seq + SEQ_INCREMENT_STEP)) { 129 atomic_store(&key_map[i].key_destructor, reinterpret_cast<uintptr_t>(key_destructor)); 130 *key = i | KEY_VALID_FLAG; 131 return 0; 132 } 133 } 134 } 135 return EAGAIN; 136 }
-
pthread_setspecific方法
178 int pthread_setspecific(pthread_key_t key, const void* ptr) {
//KeyInValidRange判断key值有没有超出范围
179 if (__predict_false(!KeyInValidRange(key))) {
180 return EINVAL;
181 }
182 key &= ~KEY_VALID_FLAG;
183 uintptr_t seq = atomic_load_explicit(&key_map[key].seq, memory_order_relaxed);
184 if (__predict_true(SeqOfKeyInUse(seq))) {
185 pthread_key_data_t* data = &get_thread_key_data()[key];
186 data->seq = seq;
187 data->data = const_cast<void*>(ptr);
188 return 0;
189 }
190 return EINVAL;
191 }
pthread_key_t 实际为int类型
→key_map数组
50 struct pthread_key_internal_t {
51 atomic_uintptr_t seq;
52 atomic_uintptr_t key_destructor;
53 };
54
55 static pthread_key_internal_t key_map[BIONIC_PTHREAD_KEY_COUNT];
根据http://xinyiworld.top/wordpress_it/?p=14519可以知道atomic_uintptr_t为类型为unsigned long
类型的原子变量
//todo
pthread_setname_np.cpp
- pthread_setname_np(设置线程名称)
83 int pthread_setname_np(pthread_t t, const char* thread_name) { 84 ErrnoRestorer errno_restorer; 85 86 size_t thread_name_len = strlen(thread_name); 87 if (thread_name_len >= MAX_TASK_COMM_LEN) return ERANGE; 88 89 // Setting our own name is an easy special case. 90 if (t == pthread_self()) { 91 return prctl(PR_SET_NAME, thread_name) ? errno : 0; 92 } 93 94 // We have to set another thread's name. 95 int fd = __open_task_comm_fd(t, O_WRONLY, "pthread_setname_np"); 96 if (fd == -1) return errno; 97 98 ssize_t n = TEMP_FAILURE_RETRY(write(fd, thread_name, thread_name_len)); 99 close(fd); 100 101 if (n == -1) return errno; 102 if (n != static_cast<ssize_t>(thread_name_len)) return EIO; 103 return 0; 104 }
向
/proc/进程id/task/线程id/comm
文件中写入线程名称
pthread_self.cpp
29 #include "pthread_internal.h"
30
31 pthread_t pthread_self() {
32 return reinterpret_cast<pthread_t>(__get_thread());
33 }
ndk_cruft.cpp
- __get_thread
366 // Various third-party apps contain a backport of our pthread_rwlock implementation that uses this. 367 pthread_internal_t* __get_thread() { 368 return __real_get_thread(); 369 }
__real_get_thread实现位置 ?
0 条评论