linux——pthread_create()到底可以创建多少个线程?

浅谈系统线程数限制 Linux进程与线程 概念就不提了,Richard Stevens的描述: > fork is expensive. Memory is copied from the parent to the child, all descriptors are duplicated in the child, and so on. Current implementations use a te... 阅读详情

pthread_create()到底可以创建多少个线程?

今天在查看pthread_create()函数的使用方法时,比较好奇它到底可以创建多少个线程呢?下面就来测试一番,以下是测试过程。

#include <pthread.h>

#include <stdio.h>

#include <string.h>

#include <unistd.h>

void *ThreadFunc()
{
    static int count = 1;
    printf ("Create thread %d\n", count);
    count++;
}
main(void)

{
    int     err;
    pthread_t tid;
    while (1)
    {
           err= pthread_create(&tid, NULL, ThreadFunc, NULL);
           if(err != 0){
               printf("can't create thread: %s\n",strerror(err));
           break;
           }
          usleep(2000);
    }
}

编译,运行:

gcc pthread_test.c  -o pthread_test  -lpthread
./pthread_test 

运行结果如下:
在这里插入图片描述
可以看到linux在创建了381后进程后,报错;Resource temporarily unavailable,资源暂时不可用。那为什么会是381个呢?我们可以使用ulimit -a 来查看自己系统默认设置中线程栈的大小,如下:
在这里插入图片描述
可以看到,stack size 是8192K,及8M。max user processer 是7864个。为什么创建了381个就满了呢?下面看下计算过程:
32位linux下的进程用户空间是3G,即3072M, 3072 M/8M=384个。为什么实际只能创建381呢?这个实际原因还没找到,有知道的网友可以留言告知一下。

修改线程默认栈空间大小

(1)以下是linux查看并修改线程默认栈空间大小的一些方法:
a、通过命令 ulimit -s 查看linux的默认栈空间大小,默认情况下 为8192即8M

b、通过命令 ulimit -s 设置大小值 临时改变栈空间大小:ulimit -s 10240, 即修改为10M

c、可以在/etc/rc.local 内 加入 ulimit -s 10240 则可以开机就设置栈空间大小为10M

d、在/etc/security/limits.conf 中也可以改变栈空间大小:
增加设置:
soft stack 10240
重启后,执行ulimit -s 即可看到改为10240 即10M。
(2)那为啥linux要限制用户进程的栈内存大小?
Why does Linux have a default stack size soft limit of 8 MB?
The point is to protect the OS.
Programs that have a legitimate reason to need more stack are rare. On the other hand, programmer mistakes are common, and sometimes said mistakes lead to code that gets stuck in an infinite loop. And if that infinite loop happens to contain a recursive function call, the stack would quickly eat all the available memory. The soft limit on the stack size prevents this: the program will crash but the rest of the OS will be unaffected.

Note that as this is only a soft limit, you can actually modify it from within your program (see setrlimit(2): get/set resource limits) if you really need to.

线程资源的回收

(3)每次用完进程后都自动的回收资源,继续测试结果:

#include <pthread.h>

#include <stdio.h>

#include <string.h>

#include <unistd.h>

void *ThreadFunc()
{
    static int count = 1;
    printf ("Create thread %d\n", count);
    pthread_detach(pthread_self()); //标记为DETACHED状态,完成后释放自己占用的资源。
    count++;
}
main(void)
{
    int     err;
    pthread_t tid;
    while (1)
    {
           err= pthread_create(&tid, NULL, ThreadFunc, NULL);
           if(err != 0){
               printf("can't create thread: %s\n",strerror(err));
           break;
           }
          usleep(2000);
    }
}

在这里插入图片描述
可以看到程序一直在无限循环创建线程,只能使用ctrl+c暂停了。也就是说如我们每次用完线程就释放点资源,是可以创建无限个线程的。线程资源的回收主要有两种:
(a)某个线程完成后,自己主动释放掉资源。使用pthread_detach ( pthread_self ( ) )来释放线程所占用的内存资源(线程内核对象和线程堆栈)。这样就可以创建更多的线程,而不会出现资源暂时不可用的错误了。
如果进程中的某个线程执行了pthread_detach(th),则th线程将处于DETACHED状态,这使得th线程在结束运行时自行释放所占用的内存资源。
(b) 某个线程完成后,另一个线程来释放这个线程的资源。在另一个线程B中调用 int pthread_join(pthread_t thread, void **retval)函数,B线程会一直等待A线程完成,当A线程执行完后,B会把A线程的资源回收回去。举个简单的例子,如下;

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
#include <string.h>
 
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 *thr_fn(void *arg)
{
    printids("new thread: ");
    return NULL;
}
 
int main(void)
{
    int err;
    pthread_t ntid;
    err = pthread_create(&ntid, NULL, thr_fn, NULL);
    if (err != 0)
        printf("can't create thread: %s\n", strerror(err));
    printids("main thread:");
    pthread_join(ntid,NULL);
    return EXIT_SUCCESS;
}

gcc main.c -o main
./main
运行结果:
main thread: pid 13073 tid 3077572816 (0xb77008d0)
new thread: pid 13073 tid 3077569392 (0xb76ffb70)
main thread会一直等待new thread完成,待其完成后,把new thread资源释放掉。
所以我们在使用线程时,注意使用pthread_detach()或pthread_join ()释放掉使用的线程资源,防止内存栈的泄漏。

线程的使用学习pthread_create函数详解(向线程函数传递参数)以及linuxpthread_join()pthread_detach()详解和#define和#ifdef的使用#if 1 1.linux线程执行和windows不同,pthread有两种状态joinable状态和unjoinable状态,如果线程是joinable状态,当线程函数自己返回退出时或pthread_exit时都不会释放线程所占用堆栈和线程描述符(总计8K多)。只有当你调用了pthread_join之后这些资源才会被释放。若是unjoinable状态的线程,这些资源在线程函数退出时或pthread_exit时自动会被释放。 阅读详情

相关推荐

Gitlab+Jenkins+Docker+Harbor+K8s+Rancher集群搭建CICD平台

本文以诺依项目为例详细记录了Kubernetes集群的部署过程以及配套DevOps环境的搭建。主要内容包括:1) 配置8个节点的软硬件环境;2) 基础环境准备(网络、防火墙、Docker等);3) 三节点Kubernetes集群部署;4) GitLab代码仓库安装;5) Harbor私有镜像仓库搭建;6) Jenkins持续集成工具配置;7) 基于若依项目的CI/CD实践;8) Rancher集群管理工具部署。

hickman2023的博客 1154

Linux 系统线程数量上限是多少

Linux 系统中单个进程的最大线程数有其最大的限制 PTHREAD_THREADS_MAX。 这个限制可以在/usr/include/bits/local_lim.h中查看 ,对 linuxthreads 这个值一般是 1024,对于 nptl 则没有硬性的限制,仅仅受限于系统的资源。 这个系统的资源主要就是线程的 stack 所占用的内存,用 ulimit -s 可以查看默认的线程栈大小,一般...

学亮编程手记 4797

OpenTCS打造移动机器人交通管制系统(四)

先分析下OpenTCS的一些策略方面的东西,这是OpenTCS的基础。 首先需要先明确下OpenTCS内核中的三个概念: 路由(Route) : 决定了车辆通过什么样的方式和算法来获得一段路径,未来车辆将沿着此路径运行。 派遣(Dispacher): 决定了一个订单应该关联哪一辆小车,即为订单分配车辆和为车辆分配订单。 调度(schedule):狭义上的调度,交通管制的核心,决定了何时分配...

白色冰激凌的技术专栏 5238

一个进程到底可以创建多少线程

一个进程拥有的进程数

qq_39329062的博客 2204

linux创建线程pthread_create

也就是说是当我们创建线程pthread之后,两个线程都在执行,证明创建成功。另外,可以看到创建线程pthread时候,传入的参数被正确打印。这个函数是一个线程阻塞的函数,调用它的函数将一直等待到被等待的线程结束为止,当函数返回时,被等待线程的资源被收回。如果执行成功,将返回0,如果失败则返回一个错误号。第二个参数为一个用户定义的指针,它可以用来存储被等待线程的返回值。函数pthread_join用来等待一个线程的结束。第三个参数是线程运行函数的地址。最后一个参数是运行函数的参数。

m0_74282605的博客 496

【c语言多线程编程】关于pthread_create()pthread_join()的多线程详解

pthread_join() 函数会一直阻塞调用它的线程,直至目标线程执行结束(接收到目标线程的返回值),阻塞状态才会解除。再次强调,一个线程执行结束的返回值只能由一个 pthread_join() 函数获取,当有多个线程调用 pthread_join() 函数获取同一个线程的执行结果时,哪个线程最先执行 pthread_join() 函数,执行结果就由那个线程获得,其它线程pthread_join() 函数都将执行失败。对于一个默认属性的线程 A 来说,线程占用的资源并不会因为执行结束而得到释放。

笑着的程序员的博客 2167

线程pthread_create()函数

总述:pthread_create是(Unix、Linux、Mac OS X)等操作系统的创建线程的函数。它的功能是创建线程(实际上就是确定调用该线程函数的入口点),在线程创建以后,就开始运行相关的线程函数。 pthread_create的返回值表示成功,返回0;表示出错,返回表示-1。 pthread_create函数如何创造线程 函数原型声明: #include &lt;pth...

wushuomin的博客 16万+

【多线程编程学习笔记3】创建线程函数pthread_create()详解

申明:本学习笔记是在该教程的基础上结合自己的学习情况进行的总结,不是原创,想要看原版的请看C语言中文网的多线程编程(C语言+Linux),该网站有很多好的编程学习教程,尤其是关于C语言的。 前面章节中,我们通过调用 pthread_create() 函数成功创建了多个线程,本节就给大家详细讲解 pthread_create() 函数的用法。 pthread_create() 函数声明在<pthread.h>头文件中,语法格式如下: int pthread_create(pthread_t *.

qq_41854911的博客 1万+

linux创建线程pthread_create()函数

创建线程是每个linux开发者都会用到的。在这里介绍一下pthread_create()函数。我们来看一看怎么创造一个线程。 首先查看pthread_create()函数的定义: PTHREAD_CREATE(3) Linux Programmer's Manual PTHREAD_CREATE(3) NAME top pthread_create - create a new thread SYNOPSIS top

StevenYang2008的博客 3355

Linux创建线程实例pthread_create()

文章目录编程环境:线程:已经程序是多线程构成:pthread_create():写一个例子:例子一:例子二:下载地址: 简 述: 前面几篇,学习了 Linux 下多进程使用 fork() 分析的其构造和原理;这里进一步,探究一下如何创建线程,以及多线程和多进程之间的差异。最后写几个实例;验证分析。 编程环境: ????: uos20 ???? gcc/g++ 8.3 ???? gdb8.0 ????: Ma...

9402

线程pthread_create()

总述:pthread_create是(Unix、Linux、Mac OS X)等操作系统的创建线程的函数。它的功能是创建线程(实际上就是确定调用该线程函数的入口点),在线程创建以后,就开始运行相关的线程函数。 pthread_create的返回值表示成功,返回0;表示出错,返回表示-1。 pthread_create函数如何创造线程函数原型声明: #include <pthread.h> int pthread_create( pthread_t *res

CodeAllen嵌入式 3万+

C语言用pthread.h创建线程

C语言的线程pthread.h的APIpthread.h的示例 C语言的线程库 在Linux系统上,可使用pthread.h创建线程。比如pthread_create()pthread.h符合POSIX标准,适用于类Unix、Linux系统。也有兼容Windows的版本——pthreads-w32。 编译时要链接pthread库,比如:gcc test.c -o test -l pt...

LeoHsiao的博客 1万+

Linux线程(2)——创建、终止和回收(pthread_create()pthread_exit()pthread_join()

就像每个进程都有一个进程 ID 一样,每个线程也有其对应的标识,称为线程 ID。进程 ID 在整个系统中是唯一的,但线程 ID 不同,线程 ID 只有在它所属的进程上下文中才有意义。进程 ID 使用 pid_t 数据类型来表示,它是一个非负整数。该函数调用总是成功,返回当前线程线程 ID。如果两个线程 ID t1 和 t2 相等,则 pthread_equal()返回一个非零值;否则返回 0。

cj_lsk的博客 2870

linux下的线程创建相关API函数(pthread _createpthread _join、pthread _detach、pthread _concel、pthread _kill)

linux下的线程创建以及线程通讯相关API函数线程创建相关API函数pthread _create创建线程函数)1. 头文件2. 函数原型3. 参数说明4. 返回值:5. 举例说明:6、传递不同参数pthread_join()1. 含义2. 背景3. 函数原型4. 第二个参数说明5. 终止状态(线程返回值)6、回收子线程的返回值pthread_detach()1、背景2、函数原型3、返回值4、detached状态 线程创建相关API函数 pthread _create创建线程函数) 1. 头文件 #

JMW1407的博客 3004

linux创建线程pthread_create pthread_join

pthread_create 函数简介: pthread_create是UNIX环境创建线程函数 头文件: #include<pthread.h> 函数声明: int pthread_create(pthread_t *restrict tidp,const pthread_attr_t *restrict_attr,void*(*start_rtn)(void*),void *r...

blog 3746

Linux线程控制{fork() / vfork / clone/pthread_join()/pthread_cancel()}

线程控制,初次使用linux下的线程接口。线程创建/线程等待/线程替换/线程终止/线程分离/线程取消

Ape's IT Blog 1568

linux系统编程学习笔记】第八节:线程初认识(pthread_create 线程创建pthread_join  线程回收、pthread_exit  线程退出)

线程初认识 线程的基本概念 线程特点及API pthread_create 线程创建 pthread_join 线程回收 pthread_exit 线程退出 例程: 线程的基本概念 线程实际上是应用层的概念,一个进程内部的多条线程共享了大部分资源,但是还是有一些信息是各自独立的一一比如其运行状态,当一个线程处于睡眠的时候,另一条线程可以正在运行,而或许有些线程已经变成僵尸了!就像一个人是如果是多线程的,他就可以做到一边睡觉一边吃饭一边在洗澡!正是利用线程状态独立的特征,程...

qq_44796935的博客 1930

linux线程pthread_create

Linux系统下的多线程遵循POSIX线程接口,称为pthread #include /*功能:创建线程参数: thread_id: 指向线程标识符的指针 attr: 设置线程属性,NULL为默认属性 start_routine: 指向线程运行函数的指

lingdxuyan的专栏 5459

Linux——pthread_create()

1 pthread_create pthread_create是(Unix、Linux、Mac OS X)等操作系统的创建线程的函数。它的功能是创建线程(实际上就是确定调用该线程函数的入口点),在线程创建以后,就开始运行相关的线程函数。 函数原型声明: #include <pthread.h> int pthread_create( pthread_t *restrict tidp, //指向新创建线程标识符的指针 const p...

sy_123a的专栏 1782

Linux线程学习(一)pthread_create

Linux系统下的多线程遵循POSIX线程接口,称为pthread。 #include int pthread_create(pthread_t *restrict tidp, const pthread_attr_t *restrict attr, void *(*start_rtn)(void),  void *restrict arg); Returns: 0 if

笑也有泪的专栏 7609

三维重建代码合集,三维重建应用,matlab

基于matlab的一些三维场景建模代码,个人学习使用。

上一篇: zedboard —pocketsphinx-5prealpha最新版库移植至zedboard(七)
下一篇: linux——setjmp()和longjmp()函数的使用
夜风~
博客等级 码龄12年 1185粉丝 134原创
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值