Linux线程JOINABLE与DETACHED的区别
目录
- Linux下两种类型线程的创建
- joinable属性的线程
- detached属性的线程
- 代码示例
Linux下两种类型线程的创建
Linux下多线程编程时,线程有两种属性,一种是joinable,一种是detached。
joinable属性的线程
如果是joinable的线程,那么必须使用pthread_join()来等待线程结束,否则线程所占用的资源不会得到释放,会造成资源泄露。
其他线程或父线程如果没有调用pthread_join去做相关资源的释放(pthread id等),该线程运行结束后资源就得不到释放,所在进程的pthread id数目就可能会累积到达最大数目PTHREAD_THREADS_MAX,此时该进程就不能再创建线程了,因为pthread id等资源被用光了,这是在多线程编程中很常见的bug之一。
一个joinable线程,只能有一个pthread_join()来等待结束,如果有多个,则只有第一个执行到的有效,其他的都会直接返回,具体错误信息由pthread_join()函数的返回值返回。
pthread_create()函数默认创建的线程是joinable属性的,或者也可以使用下述代码显示的将线程设为joinable属性:
pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
pthread_create(&tid, &attr, callback, (void *)context);
detached属性的线程
如果想创建一个线程,但又不想使用pthread_join()等待该线程结束,那么可以创建一个detached的线程。detached属性的线程,在结束的时候,会自动释放该线程所占用的资源。
detached不需要,也不能使用pthread_join()来等待线程结束。
可以用如下代码在来设置并创建detached线程:
pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
pthread_create(&tid, &attr, callback, (void *)context);
代码示例
包含两种属性线程的代码示例:
#include <pthread.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h> pthread_t pid_joinable;
pthread_t pid_detached; pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; int count; void printids(const char *s)
{ pid_t pid; pthread_t tid; pid = getpid(); tid = pthread_self(); printf("%s pid %u tid %u (0x%x)\n", s, (unsigned int)pid, (unsigned int)tid, (unsigned int)tid);
} void *cb_joinable(void *arg)
{ printids("New thread joinable begin"); printids("New thread joinable:"); int i=0; for ( ; i<5; ++i) { pthread_mutex_lock(&mutex); printf("joinable runing %d\n", count++); pthread_mutex_unlock(&mutex); sleep(1);}return ((void*)123);
} void *cb_detached(void *arg)
{ printids("New thread detached begin"); printids("New thread detached:"); int i=0; for ( ; i<10; ++i) { pthread_mutex_lock(&mutex); printf("detached runing %d\n", count++); pthread_mutex_unlock(&mutex); sleep(1); } return ((void*)456);
} int main(void)
{ int err; count = 0; pthread_mutex_init(&mutex, NULL); err = pthread_create(&pid_joinable, NULL, cb_joinable, NULL); if ( 0 != err ) { printf("can't create joinable thread: %s\n", strerror(err)); } pthread_attr_t attr; pthread_attr_init(&attr); pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED); err = pthread_create(&pid_detached, &attr, cb_detached, NULL); if ( 0 != err ) { printf("can't create detached thread:%s\n", strerror(err)); } pthread_attr_destroy (&attr); int **ret; err = pthread_join(pid_joinable, (void**)ret); if ( err == 0 ) { printf("joinable return %d\n", *ret); } else { printf("can't pthread_join pid_joinable thread: %s\n", strerror(err)); } err = pthread_join(pid_detached, (void**)ret); if ( err == 0 ) { printf("pid_detached return %d\n", *ret); } else { printf("can't pthread_join pid_detached thread: %s\n", strerror(err)); } pthread_mutex_destroy(&mutex); return 0;
}
编译运行:
g++ thread.cpp -o test -pthread
./test
输出结果如下所示:
New thread joinable begin pid 3330 tid 85509888 (0x518c700)
New thread joinable: pid 3330 tid 85509888 (0x518c700)
joinable runing 0
New thread detached begin pid 3330 tid 77117184 (0x498b700)
New thread detached: pid 3330 tid 77117184 (0x498b700)
detached runing 1
joinable runing 2
detached runing 3
detached runing 4
joinable runing 5
joinable runing 6
detached runing 7
detached runing 8
joinable runing 9
detached runing 10
joinable return 123
can't pthread_join pid_detached thread: Invalid argument
从结果可以看出,main函数阻塞到了这行代码:
err = pthread_join(pid_joinable, (void**)ret);
等线程工作完成后,通过此处对线程资源做了释放。
而pid_detached线程为detached属性,所以强行调用pthread_join函数会报错:
can't pthread_join pid_detached thread: Invalid argument
Linux线程JOINABLE与DETACHED的区别相关推荐
- linux 线程与进程的简单区别
一.进程与线程的区别 一个进程至少包含一个线程,线程可以在同一时刻做不止一件事情:进程是线程的容器,里面可以包含很多个线程. 进程:是资源分配的最小单位 线程:是程序执行的最小单位 区别一: 进程:父 ...
- 线程的状态----joinable和detached
在任何一个时间点上,线程是可结合的(joinable),或者是分离的(detached).一个可结合的线程能够被其他线程收回其资源和杀死:在被其他线程回收之前,它的存储器资源(如栈)是不释放的.相反, ...
- Linux线程退出、资源回收、资源清理的方法
首先说明线程中要回收哪些资源,理解清楚了这点之后在思考资源回收的问题. 1.子线程创建时从父线程copy出来的栈内存; 线程退出有多种方式,如return,pthread_exit,pthread_c ...
- linux 线程 进程经典文章
进程是程 序在计算机上的一次执行活动.当你运行一个程序,你就启动了一个进程.显然,程序是 死的(静态的),进程是活的(动态的).进程可以分为系统进程和用户进程.凡是用于完成操作系统的各种功能的进程就是 ...
- 【Linux开发】彻底释放Linux线程的资源
Linux系统中程序的线程资源是有限的,表现为对于一个程序其能同时运行的线程数是有限的.而默认的条件下,一个线程结束后,其对应的资源不会被释放,于是,如果在一个程序中,反复建立线程,而线程又默认的退出 ...
- linux线程池的使用
Linux下通用线程池的创建与使用[ZT] 收藏 本文给出了一个通用的线程池框架,该框 架将与线程执行相关的任务进行了高层次的抽象,使之与具体的执行任务无关.另外该线程池具有动态伸缩性,它能根据执 ...
- linux线程的创建与删除
linux线程的创建与删除 使用linux线程时,编译时需要包含-pthread选项. Linux通用API返回0表示成功,返回-1表示失败,并设置errno以标识错误原因.但Pthreads相关的A ...
- linux线程的实现【转】
转自:http://www.cnblogs.com/zhaoyl/p/3620204.html 首先从OS设计原理上阐明三种线程:内核线程.轻量级进程.用户线程 内核线程 内核线程就是内核的分身,一个 ...
- Linux 线程与进程,以及通信
http://blog.chinaunix.net/uid-25324849-id-3110075.html 部分转自:http://blog.chinaunix.net/uid-20620288-i ...
最新文章
- CentOS7下Django安装
- 如何在Google Chrome浏览器中启动JavaScript调试器?
- 类似百度输入框自动完成
- NDK avi播放器
- 搞机器学习需要数学基础吗?
- 第三次学JAVA再学不好就吃翔(part75)--集合概述
- 走近分形与混沌(part12)--随机过程与混沌
- 七牛云 转码_七牛云存储 - 七牛 php sdk 上传 转码 问题
- Dos批处理编程常用命令
- 深度学习(六十四)Faster R-CNN物体检测
- 分布式事务模型--Saga
- python3.7.4怎么运行_记一次win7在python3.7.4环境启动ride报错解决
- tidb 架构 ~Tidb学习系列(5)
- DM笔记之安装1:DM7 For NeoKylin A6
- 数据管理知识体系指南(第二版)-第四章——数据架构-学习笔记
- 如何用windows xp自带的画图工具画箭头
- exe文件关联被更改的解决方法
- 补交20145226蓝墨云班课 -- MyOD
- 能量原理与变分法笔记03:证明两点之间直线最短
- scratch3.0-界面介绍
热门文章
- java printwriter乱码_PrintWriter返回乱码的分析及解决
- 贝佐斯:管理亚马逊的20条经营理念
- 猪身上的肉都分哪些部位?
- Ajax之onreadystatechange属性详解
- Reactor设计模式 -- 基于EpollET模式
- uniapp - 超详细的 H5 公众号网页微信登录示例代码,提供从 0-1 公众号配置及详细注释代码(站在新手小白的角度)第三方微信授权登录的实现!!
- Catia 端面凸轮设计
- matlab 作图所用特殊符号及希腊字母总结
- java关于广告的项目_基于jsp的广告管理系统-JavaEE实现广告管理系统 - java项目源码...
- Three.js及React Three Fiber开发