Linux 线程--那一年, 我们一起忽视的pthread_join
前言:
通过linux的pthread库, 相信大家对创建/销毁线程肯定很熟悉, 不过对pthread_join是否知道的更多呢?
实验:
先编写一个常规的程序
#include <pthread.h> #include <stdio.h>
#include <string.h> void *thread_rountine(void * /*args*/) {
printf("thread %lu work\n", pthread_self());
} int main()
{ pthread_t tid; // *) 创建线程
pthread_create(&tid, NULL, thread_rountine, NULL); // *) 等待线程结束
pthread_join(tid, NULL); return 0; }
评注: 这是简单的关于线程创建, 以及通过pthread_join阻塞等待子线程退出的例子
pthread_join是否真的只是为了执行顺序, 等待子线程退出的一种机制? 难道就没有其他作用了吗?
答案是肯定的, 我们先来写个程序, 做下对比:
#include <sys/time.h>
#include <sys/resource.h> #include <pthread.h> #include <stdio.h>
#include <string.h> void *thread_rountine(void * /*args*/) {
//pthread_detach(pthread_self()); ==> (2)
} int main()
{
rlimit rl;
getrlimit(RLIMIT_NPROC, &rl); for ( int i = 0; i < rl.rlim_cur; i++ ) {
pthread_t tid;
int ret = pthread_create(&tid, NULL, thread_rountine, NULL);
if ( ret != 0 ) {
printf("error_msg => %s\n", strerror(ret));
break;
}
// pthread_join(tid, NULL); ==> (1)
} return 0; }
评注: 这边我们去掉了(1)pthread_join, (2) pthread_detach
最终的程序输出结果为:
error_msg => Resource temporarily unavailable
我们可以大胆地猜想进程的线程数有个限制, 那我们的程序究竟在那个环节出错了? 疏忽什么导致线程资源没被完全收回?
和Java开发多线程程序相比, 觉得搞java的人实在太幸福了.
在回到原问题, 如果我们添加(1)pthread_join, 或者(2)pthread_detach, 问题解决了.
我们查下man, 看看"专家"如何解说pthread_join
Failure to join with a thread that is joinable (i.e., one that is not detached), produces a "zombie thread". Avoid doing this, since each zombie thread consumes some system resources, and when enough zombie threads have accumulated, it will no longer be possible to create new threads (or processes).
评注: 如果没有对joinable的线程, 作pthread_join, 会导致线程成为"zombie thread", 依旧会占据这个资源. 这也就不难理解了,为何明明都是短任务线程, 没有加pthread_join, 主线程就不能再创建线程了. pthread_join其实作了部分线程销毁的工作. 另一方面, 子线程能通过pthread_detach函数, 在线程自身退出时做好清理工作.
这边有个疑惑:
在linux中, 如何限制进程的线程数? 线程数的上限由什么来限定?
后记:
真的是好久没写c++程序了, 也挺想念的, 不知何时还有机会做linux下c/c++开发, 还是never?
Linux 线程--那一年, 我们一起忽视的pthread_join的更多相关文章
- [转载]Linux 线程实现机制分析
本文转自http://www.ibm.com/developerworks/cn/linux/kernel/l-thread/ 支持原创.尊重原创,分享知识! 自从多线程编程的概念出现在 Linux ...
- linux线程的实现
首先从OS设计原理上阐明三种线程:内核线程.轻量级进程.用户线程 内核线程 内核线程就是内核的分身,一个分身可以处理一件特定事情.这在处理异步事件如异步IO时特别有用.内核线程的使用是廉价的,唯一使用 ...
- linux线程的实现【转】
转自:http://www.cnblogs.com/zhaoyl/p/3620204.html 首先从OS设计原理上阐明三种线程:内核线程.轻量级进程.用户线程 内核线程 内核线程就是内核的分身,一个 ...
- Linux线程-创建
Linux的线程实现是在内核以外来实现的,内核本身并不提供线程创建.但是内核为提供线程[也就是轻量级进程]提供了两个系统调用__clone()和fork (),这两个系统调用都为准备一些参数,最终都用 ...
- Linux线程学习(一)
一.Linux进程与线程概述 进程与线程 为什么对于大多数合作性任务,多线程比多个独立的进程更优越呢?这是因为,线程共享相同的内存空间.不同的线程可以存取内存中的同一个变量.所以,程序中的所有线程都可 ...
- Linux线程学习(二)
线程基础 进程 系统中程序执行和资源分配的基本单位 每个进程有自己的数据段.代码段和堆栈段 在进行切换时需要有比较复杂的上下文切换 线程 减少处理机的空转时间,支持多处理器以及减少上下文切换开销, ...
- Linux 线程(进程)数限制分析
1.问题来源公司线上环境出现MQ不能接受消息的异常,运维和开发人员临时切换另一台服务器的MQ后恢复.同时运维人员反馈在出现问题的服务器上很多基本的命令都不能运行,出现如下错误:2. 初步原因分析和 ...
- Linux 线程与进程,以及通信
http://blog.chinaunix.net/uid-25324849-id-3110075.html 部分转自:http://blog.chinaunix.net/uid-20620288-i ...
- linux 线程的内核栈是独立的还是共享父进程的?
需要考证 考证结果: 其内核栈是独立的 206 static struct task_struct *dup_task_struct(struct task_struct *orig) 207 { 2 ...
随机推荐
- node.js安装及grunt插件,如何进行脚本压缩
http://gruntjs.com/pluginshttp://gruntjs.com/getting-startedhttp://gruntjs.com/configuring-tasks#glo ...
- caches 文件夹删除
模拟器 可以 删除 真机不行
- C++-多重继承的注意点
1, 钻石型多重继承如果不想要底部的类有重复的变量,则需要声明为virtual继承 class File{...}; class InputFile: virtual public File{..}; ...
- Rhel6-heartbeat配置文档
系统环境: rhel6 x86_64 iptables and selinux disabled 主机: 192.168.122.119 server19.example.com 192.168.12 ...
- CSU 1160 A(Contest #3)
Description 把十进制整数转换为十六进制,格式为0x开头,10~15由大写字母A~F表示. Input 每行一个整数x,0<= x <= 2^31. Output 每行输出对应的 ...
- Android 应用按两下返回键退出应用程序
在android应用开发中,有时候应用会用到按两下返回键退出应用的功能,今天介绍一下这个功能,直接上代码: @Override public boolean dispatchKeyEvent(KeyE ...
- 自定义ImageView
package com.example.myimageview; import android.content.Context;import android.graphics.Bitmap;impor ...
- printf的格式输出
格式字符 意义 d 以十进制形式输出带符号整数(正数不输出符号) o 以八进制形式输出无符号整数(不输出前缀0) x,X 以十六进制形式输出无符号整数(不输出前缀Ox) u 以十进制形式输出无符号整数 ...
- ios页面间传递参数四种方式
ios页面间传递参数四种方式 1.使用SharedApplication,定义一个变量来传递. 2.使用文件,或者NSUserdefault来传递 3.通过一个单例的class来传递 4.通过Dele ...
- $.noop()和$.map()函数
最近在项目中发现$.noop()函数,因以前没使用过故查询下,现整理如下: jQuery.noop()函数是一个空函数,它什么也不做. 当某些时候你需要传入函数参数,而且希望它什么也不做的时候,你可以 ...