关于pthread_detach(pthread_self())

本文探讨了Linux环境下线程管理的概念,特别是pthread库中线程分离的重要性。解释了joinable与unjoinable状态的区别,以及如何通过pthread_detach函数合理管理线程资源。
 

近来发现 在线程函数第一行调用 pthread_detach(pthread_self()) 返回值是22不是0,后来在网上找到以下话语:

linux线程执行和windows不同,pthread有两种状态joinable状态和unjoinable状态,如果线程是joinable状态,当线程函数自己返回退出时或pthread_exit时都不会释放线程所占用堆栈和线程描述符(总计8K多)。只有当你调用了pthread_join之后这些资源才会被释放。
若是unjoinable状态的线程,这些资源在线程函数退出时或pthread_exit时自动会被释放。

unjoinable属性可以在pthread_create时指定,或在线程创建后在线程中pthread_detach自己,如:pthread_detach(pthread_self()),将状态改为unjoinable状态,确保资源的释放。或者将线程置为joinable,然后适时调用pthread_join.

在程序运行中检查/proc/ <pid> /maps文件,若看到大概8K左右的很多虚拟内存碎片,基本上可以确认是线程资源泄漏造成的300个线程后pthread_create失败。

不知是否因为自己,先对要创建的线程做了以下属性设定,
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);

然后又在线程函数中使用
pthread_detach(pthread_self());

两段代码作用有冲突。

===============================================================================

pthread_detach(threadid)和pthread_detach(pthread_self())的区别应该是调用他们的线程不同,没其他区别。

pthread_detach(threadid)函数的功能是使线程ID为threadid的线程处于分离状态,一旦线程处于分离状态,该线程终止时底层资源立即被回收;否则终止子线程的状态会一直保存(占用系统资源)直到主线程调用pthread_join(threadid,NULL)获取线程的退出状态。
通常是主线程使用pthread_create()创建子线程以后,一般可以调用pthread_detach(threadid)分离刚刚创建的子线程,这里的threadid是指子线程的threadid;如此以来,该子线程止时底层资源立即被回收;
被创建的子线程也可以自己分离自己,子线程调用pthread_detach(pthread_self())就是分离自己,因为pthread_self()这个函数返回的就是自己本身的线程ID。

### `pthread_detach` 和 `pthread_self` 的使用方法 #### `pthread_detach` 的作用 `pthread_detach` 用于将一个线程设置为“分离状态”,即该线程在结束时会自动释放资源,而不需要其他线程调用 `pthread_join` 来回收其资源。分离线程的生命周期管理更加简单,适用于不需要获取线程退出状态的场景。调用 `pthread_detach` 后,线程一旦终止,其所有资源都会被系统自动回收,不再需要显式地等待线程结束 [^1]。 ```c #include <pthread.h> #include <stdio.h> #include <unistd.h> void* thread_func(void* arg) { printf("分离线程运行中...\n"); sleep(2); printf("分离线程结束\n"); return NULL; } int main() { pthread_t tid; pthread_create(&tid, NULL, thread_func, NULL); pthread_detach(tid); // 将线程设置为分离状态 printf("主线程继续执行,不等待分离线程\n"); sleep(3); // 确保主线程在分离线程结束后才退出 return 0; } ``` #### `pthread_self` 的作用 `pthread_self` 函数用于获取当前线程的线程标识符(`pthread_t` 类型)。该标识符可以用于比较线程是否为同一个,或者作为参数传递给其他线程相关函数(如 `pthread_cancel` 或 `pthread_detach`) [^2]。 ```c #include <pthread.h> #include <stdio.h> void* thread_func(void* arg) { pthread_t self = pthread_self(); printf("子线程 ID: %#lx\n", self); return NULL; } int main() { pthread_t tid; pthread_create(&tid, NULL, thread_func, NULL); pthread_t main_tid = pthread_self(); printf("主线程 ID: %#lx\n", main_tid); pthread_join(tid, NULL); return 0; } ``` #### `pthread_detach` 和 `pthread_self` 的结合使用 在某些情况下,线程可能希望将自己设置为分离状态,这时可以结合 `pthread_self` 来实现: ```c #include <pthread.h> #include <stdio.h> #include <unistd.h> void* thread_func(void* arg) { pthread_detach(pthread_self()); // 将当前线程设置为分离状态 printf("分离线程 ID: %#lx\n", pthread_self()); sleep(1); printf("分离线程结束\n"); return NULL; } int main() { pthread_t tid; pthread_create(&tid, NULL, thread_func, NULL); printf("主线程继续执行,不等待分离线程\n"); sleep(2); // 确保主线程在分离线程结束后才退出 return 0; } ``` #### 多线程编程中的注意事项 - **线程分离与连接的冲突**:如果一个线程已经被分离,再次调用 `pthread_join` 会导致错误。因此,必须确保一个线程要么被分离,要么被连接,不能同时进行 [^3]。 - **线程取消与分离的关系**:当一个线程被取消(`pthread_cancel`)时,如果该线程是分离状态,则其资源会立即被释放,而不会等待其他线程调用 `pthread_join` [^4]。 - **线程标识符的可比性**:`pthread_t` 类型的值可以用于比较两个线程是否为同一个,通常使用 `pthread_equal` 函数进行比较。 ---
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值