Linux 线程--那一年, 我们一起忽视的pthread_join

前言:
  通过linux的pthread库, 相信大家对创建/销毁线程肯定很熟悉, 不过对pthread_join是否知道的更多呢?
实验:
  先编写一个常规的程序

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#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是否真的只是为了执行顺序, 等待子线程退出的一种机制? 难道就没有其他作用了吗?
  答案是肯定的, 我们先来写个程序, 做下对比:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#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
  最终的程序输出结果为:

1
error_msg => Resource temporarily unavailable

  我们可以大胆地猜想进程的线程数有个限制, 那我们的程序究竟在那个环节出错了? 疏忽什么导致线程资源没被完全收回?

  和Java开发多线程程序相比, 觉得搞java的人实在太幸福了.

  在回到原问题, 如果我们添加(1)pthread_join, 或者(2)pthread_detach, 问题解决了.
  我们查下man, 看看"专家"如何解说pthread_join

1
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?

posted on   mumuxinfei  阅读(5453)  评论(0编辑  收藏  举报

编辑推荐:
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构

导航

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

统计

点击右上角即可分享
微信分享提示