目录

  • 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的区别相关推荐

  1. linux 线程与进程的简单区别

    一.进程与线程的区别 一个进程至少包含一个线程,线程可以在同一时刻做不止一件事情:进程是线程的容器,里面可以包含很多个线程. 进程:是资源分配的最小单位 线程:是程序执行的最小单位 区别一: 进程:父 ...

  2. 线程的状态----joinable和detached

    在任何一个时间点上,线程是可结合的(joinable),或者是分离的(detached).一个可结合的线程能够被其他线程收回其资源和杀死:在被其他线程回收之前,它的存储器资源(如栈)是不释放的.相反, ...

  3. Linux线程退出、资源回收、资源清理的方法

    首先说明线程中要回收哪些资源,理解清楚了这点之后在思考资源回收的问题. 1.子线程创建时从父线程copy出来的栈内存; 线程退出有多种方式,如return,pthread_exit,pthread_c ...

  4. linux 线程 进程经典文章

    进程是程 序在计算机上的一次执行活动.当你运行一个程序,你就启动了一个进程.显然,程序是 死的(静态的),进程是活的(动态的).进程可以分为系统进程和用户进程.凡是用于完成操作系统的各种功能的进程就是 ...

  5. 【Linux开发】彻底释放Linux线程的资源

    Linux系统中程序的线程资源是有限的,表现为对于一个程序其能同时运行的线程数是有限的.而默认的条件下,一个线程结束后,其对应的资源不会被释放,于是,如果在一个程序中,反复建立线程,而线程又默认的退出 ...

  6. linux线程池的使用

      Linux下通用线程池的创建与使用[ZT] 收藏 本文给出了一个通用的线程池框架,该框 架将与线程执行相关的任务进行了高层次的抽象,使之与具体的执行任务无关.另外该线程池具有动态伸缩性,它能根据执 ...

  7. linux线程的创建与删除

    linux线程的创建与删除 使用linux线程时,编译时需要包含-pthread选项. Linux通用API返回0表示成功,返回-1表示失败,并设置errno以标识错误原因.但Pthreads相关的A ...

  8. linux线程的实现【转】

    转自:http://www.cnblogs.com/zhaoyl/p/3620204.html 首先从OS设计原理上阐明三种线程:内核线程.轻量级进程.用户线程 内核线程 内核线程就是内核的分身,一个 ...

  9. Linux 线程与进程,以及通信

    http://blog.chinaunix.net/uid-25324849-id-3110075.html 部分转自:http://blog.chinaunix.net/uid-20620288-i ...

最新文章

  1. CentOS7下Django安装
  2. 如何在Google Chrome浏览器中启动JavaScript调试器?
  3. 类似百度输入框自动完成
  4. NDK avi播放器
  5. 搞机器学习需要数学基础吗?
  6. 第三次学JAVA再学不好就吃翔(part75)--集合概述
  7. 走近分形与混沌(part12)--随机过程与混沌
  8. 七牛云 转码_七牛云存储 - 七牛 php sdk 上传 转码 问题
  9. Dos批处理编程常用命令
  10. 深度学习(六十四)Faster R-CNN物体检测
  11. 分布式事务模型--Saga
  12. python3.7.4怎么运行_记一次win7在python3.7.4环境启动ride报错解决
  13. tidb 架构 ~Tidb学习系列(5)
  14. DM笔记之安装1:DM7 For NeoKylin A6
  15. 数据管理知识体系指南(第二版)-第四章——数据架构-学习笔记
  16. 如何用windows xp自带的画图工具画箭头
  17. exe文件关联被更改的解决方法
  18. 补交20145226蓝墨云班课 -- MyOD
  19. 能量原理与变分法笔记03:证明两点之间直线最短
  20. scratch3.0-界面介绍

热门文章

  1. java printwriter乱码_PrintWriter返回乱码的分析及解决
  2. 贝佐斯:管理亚马逊的20条经营理念
  3. 猪身上的肉都分哪些部位?
  4. Ajax之onreadystatechange属性详解
  5. Reactor设计模式 -- 基于EpollET模式
  6. uniapp - 超详细的 H5 公众号网页微信登录示例代码,提供从 0-1 公众号配置及详细注释代码(站在新手小白的角度)第三方微信授权登录的实现!!
  7. Catia 端面凸轮设计
  8. matlab 作图所用特殊符号及希腊字母总结
  9. java关于广告的项目_基于jsp的广告管理系统-JavaEE实现广告管理系统 - java项目源码...
  10. Three.js及React Three Fiber开发