本文已参与「新人创作礼」活动,一起开启掘金创作之路。
线程等待
- 线程等待的前提:线程能够被等待,即处于 joinable 状态。(本质是一个标志位)
因为一个线程运行起来默认拥有一个属性joinable,处于这个属性的线程退出后不会自动释放资源,必须被其他线程等待。因为线程退出后,为了保存返回值,不会自动回收线程的资源而成为僵尸线程(现象不能直观体现)。
所以选择使用pthread_join()接口实现线程等待,获取指定线程的返回值,并允许系统回收线程资源。
pthread_join()接口
int pthread_join(pthread_t thread, void **retval);
thread:要等待的指定线程id,并不能等待任意线程退出。retval:输出型参数,用于获取退出线程的退出返回值。- 返回值:成功返回
0,失败返回非零值errno。
线程分离
将线程的一个属性从joinable设置为detach属性,设置线程的detach属性退出后处于detach状态,这类线程资源直接自动被回收。这类线程不能被等待。
线程的分离对于一个线程来说,无论何处任意线程调用都可以,被等待的线程无法被等待。若是非要pthread_join等待,则会直接报错误返回。
pthread_detach()接口
线程的分离,对于一个线程来说,任意线程在任意位置调用都可以。
分离一个线程其实设置线程的detach属性。
int pthread_detach(pthread_t thread);
thread:要被分离的线程id。- 返回值:返回错误码。通常如果用户对线程的返回值不关心,则在创建线程之后直接分离线程或者在线程入口函数中第一时间分离自己。
【 小结 】:
处于
joinable状态的线程退出后不会自动释放资源,需要被等待。
处于
detach状态的线程退出后自动释放回收资源,不需要被等待。
==进程分离实例==
void *thr_start(void *arg){
//pthread_detach(pthread_self()); //分离一个指定的线程---自己也可以
sleep(3);
return "giturtle";
}
int main(int argc, char *argv[]){
pthread_t tid;
int ret = pthread_create(&tid, NULL, thr_start, NULL);
if (ret != 0) {
printf("thread create error\n");
return -1;
}
pthread_detach(tid);
char *ptr = NULL;
ret = pthread_join(tid, (void**)&ptr); //强行等待一个不能被等待的线程
if (ret == EINVAL) {
printf("this thread can not be wait!!\n");
}
printf("retval:%d--%p\n", ret, ptr);
return 0;
}
运行结果
this thread cannot be wait!
return value:22,(nil)
在后续博客会介绍包括死锁、同步与互斥、信号量,有兴趣的看官大佬可以继续了解一下~