面试题答案
一键面试- 设计思路:
- 使用Linux的线程局部存储(TLS)机制,通过
pthread_key_create
创建一个线程局部存储的键。 - 每个线程在使用资源前,将资源句柄(如数据库连接、文件描述符等)存储到这个线程局部存储键对应的位置。
- 利用
pthread_key_create
的第二个参数,设置一个清理函数,当线程退出时,该清理函数会被自动调用,用于释放线程局部存储中保存的资源。
- 使用Linux的线程局部存储(TLS)机制,通过
- 关键代码片段:
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
// 假设这是我们要管理的资源结构体
typedef struct {
int file_descriptor;
// 可以在这里添加数据库连接等其他资源
} ThreadResource;
// 线程局部存储键
pthread_key_t resource_key;
// 清理函数,用于释放资源
void resource_cleanup(void* arg) {
ThreadResource* resource = (ThreadResource*)arg;
if (resource) {
// 关闭文件描述符
if (resource->file_descriptor != -1) {
close(resource->file_descriptor);
}
free(resource);
}
}
// 线程执行函数
void* thread_function(void* arg) {
// 分配资源
ThreadResource* resource = (ThreadResource*)malloc(sizeof(ThreadResource));
if (!resource) {
perror("malloc");
pthread_exit(NULL);
}
resource->file_descriptor = open("test.txt", O_RDONLY);
if (resource->file_descriptor == -1) {
perror("open");
free(resource);
pthread_exit(NULL);
}
// 将资源存储到线程局部存储
pthread_setspecific(resource_key, resource);
// 线程的其他工作
pthread_exit(NULL);
}
int main() {
// 创建线程局部存储键,并设置清理函数
if (pthread_key_create(&resource_key, resource_cleanup) != 0) {
perror("pthread_key_create");
return 1;
}
pthread_t thread;
// 创建线程
if (pthread_create(&thread, NULL, thread_function, NULL) != 0) {
perror("pthread_create");
pthread_key_delete(resource_key);
return 1;
}
// 等待线程结束
if (pthread_join(thread, NULL) != 0) {
perror("pthread_join");
pthread_key_delete(resource_key);
return 1;
}
// 删除线程局部存储键
pthread_key_delete(resource_key);
return 0;
}
上述代码展示了如何创建线程局部存储键,在每个线程中分配资源并存储到线程局部存储,以及通过清理函数在每个线程结束时正确释放资源,从而避免内存泄漏等问题。