Linux的线程创建限制
现网有个版本上线一段时间后,通过SSH重新登陆时显示Cannot allocate memory错误,结果只能通过重启机器来恢复服务。通过分析发现是新的版本引入一个bug,某个进程会不停地创建新的线程,那么问题是Linux下一个进程可以创建多少个线程,从而会导致这个错误出现。
原因分析
问题重现,通过一个测试程序,验证错误是否会重现。
#include <iostream>
#include <pthread.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
using namespace std;
void* thr_func (void*)
{
for(;;) sleep(500);
return 0;
}
void max_thread_test ()
{
const int MAX = 4194304;
//const int MAX = 10;
for (int i = 0; i < MAX; ++i) {
int ret = 0;
if (!(i % (MAX / 100))) std::cerr << "..." << i;
pthread_attr_t attr;
pthread_attr_init(&attr);
// detached
ret = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
if (ret) {
perror("pthread_attr_setdetachstate err");
exit(1);
};
// thread stacksize
int stacksize = 16384;
pthread_attr_setstacksize(&attr, stacksize);
if (ret) {
perror("pthread_attr_setstacksize err");
exit(1);
};
pthread_t thread;
ret = pthread_create(&thread, &attr, thr_func, NULL);
if (ret) {
std::cerr << "threads created " << i << std::endl ;
perror("pthread_create");
exit(1);
}
}
std::cerr << std::endl;
std::cout << "exit (succes)" << std::endl;
}
int main()
{
max_thread_test();
for(;;) sleep(5000);
std::cout << "end" << std::endl;
return 0;
}
/*
执行后会出现类似下面的错误。
$./test_max_thread
...0threads created 2047
pthread_create: Cannot allocate memory
*/
除了内存大小限制外,还有很多内核参数的限制,但理论上一个进程可以创建的最大线程数量为:
number of threads = total virtual memory / (stack size*1024*1024)
因此,32位系统由于进程的虚拟地址空间为4G,可以创建的线程数量为3G/8M=384个线程,而64位系统的进程可以创建的线程数量为128T/8M=16777216个线程(千万级)。当然在实际使用中一般不会创建这么多线程,因为线程间的切换会占用2000+的CPU时钟周期,可能导致CPU过高。一般会根据CPU核数启用相应的线程数,尽量减少不必要的线程切换。
通过修改下面的参数,可以尽可能地创建更多的线程。
echo 1 > /proc/sys/vm/overcommit_memory
echo 1000000 > /proc/sys/kernel/threads-max
echo 10000000 > /proc/sys/vm/max_map_count
echo "4194304" > /proc/sys/kernel/pid_max
参考
理解Linux的memory overcommit:
相关热词:
本站内容来源于网络,如有侵权请与我们联系,我们会及时删除,我们深感抱歉!
注:本站所有信息仅供用于网络技术学习参考,学习中请遵循相关法律法规!
本文地址: https://v30.fanwenzhu.com/server/kaifa/11520.shtml
相关文章
热门TAG
win10 ecshop 主机 阿里云 解决 配置 C# C++ 解析 SQL语句 命令 Go语言 方法 CSS3 HTML5 CSS win7 MSSQL 服务器配置 IIS7.5 IIS7 IIS6 IIS CentOS 7 Linux oracle数据库 oracle phpcms discuz discuz教程最新文章
-
最强调试器DDD(Data Displ
时间:2021-01-07
-
Linux C语言基础IT之家——
时间:2021-01-07
-
Linux内核插入卸载模块
时间:2021-01-07
-
Linux下的c基础编程——字
时间:2021-01-06
-
Linux下的c基础编程——按
时间:2021-01-06
-
Linux下简单的cIT之家——选
时间:2021-01-06
-
linux通过/sys/class/gpio文件操
时间:2021-01-06
-
通过Java实现Linux系统下g
时间:2021-01-06
热门文章
-
开发一个Linux调试器(四):Elves和dwarv
时间:2020-12-22
-
开发一个Linux调试器(五):源码和信号
时间:2020-12-22
-
shell脚本之始
时间:2020-12-29
-
Linux下简单的cIT之家——选择法排序
时间:2021-01-06
-
linux中gdb的可视化调试
时间:2020-12-27
-
如何挑选你的第一门IT之家语言
时间:2020-12-26
-
通过Java实现Linux系统下grep指令的功能
时间:2021-01-06
-
Linux下的c基础编程——按原顺序插入元素
时间:2021-01-06
-
获取linux机器上的网卡地址
时间:2020-12-26
-
Linux内核插入卸载模块
时间:2021-01-07
