linux中每个进程的最大线程数
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/5635362/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
max thread per process in linux
提问by Hosi
I wrote a simple program to calculate the maximum number of threads that a process can have in linux (Centos 5). here is the code:
我写了一个简单的程序来计算一个进程在 linux (Centos 5) 中可以拥有的最大线程数。这是代码:
int main()
{
pthread_t thrd[400];
for(int i=0;i<400;i++)
{
int err=pthread_create(&thrd[i],NULL,thread,(void*)i);
if(err!=0)
cout << "thread creation failed: " << i <<" error code: " << err << endl;
}
return 0;
}
void * thread(void* i)
{
sleep(100);//make the thread still alive
return 0;
}
I figured out that max number for threads is only 300!? What if i need more than that? I have to mention that pthread_create returns 12 as error code.
我发现线程的最大数量只有 300!?如果我需要更多怎么办?我不得不提到 pthread_create 返回 12 作为错误代码。
Thanks before
之前谢谢
回答by Adrian Cox
Your system limits may not be allowing you to map the stacks of all the threads you require. Look at /proc/sys/vm/max_map_count
, and see this answer. I'm not 100% sure this is your problem, because most people run into problems at much larger thread counts.
您的系统限制可能不允许您映射所需的所有线程的堆栈。看看/proc/sys/vm/max_map_count
,看看这个答案。我不能 100% 确定这是您的问题,因为大多数人在线程数更大时遇到问题。
回答by johnnycrash
You will run out of memory too unless u shrink the default thread stack size. Its 10MB on our version of linux.
除非您缩小默认线程堆栈大小,否则您也会耗尽内存。它在我们的 linux 版本上为 10MB。
EDIT:Error code 12 = out of memory, so I think the 1mb stack is still too big for you. Compiled for 32 bit, I can get a 100k stack to give me 30k threads. Beyond 30k threads I get Error code 11 which means no more threads allowed. A 1MB stack gives me about 4k threads before error code 12. 10MB gives me 427 threads. 100MB gives me 42 threads. 1 GB gives me 4... We have 64 bit OS with 64 GB ram. Is your OS 32 bit? When I compile for 64bit, I can use any stack size I want and get the limit of threads.
编辑:错误代码 12 = 内存不足,所以我认为 1mb 堆栈对您来说仍然太大。编译为 32 位,我可以获得 100k 堆栈给我 30k 线程。超过 30k 个线程,我收到错误代码 11,这意味着不允许更多线程。在错误代码 12 之前,1MB 堆栈为我提供了大约 4k 个线程。10MB 为我提供了 427 个线程。100MB 给了我 42 个线程。1 GB 给我 4 ... 我们有 64 位操作系统和 64 GB 内存。你的操作系统是 32 位的吗?当我为 64 位编译时,我可以使用我想要的任何堆栈大小并获得线程限制。
Also I noticed if i turn the profiling stuff (Tools|Profiling) on for netbeans and run from the ide...I only can get 400 threads. Weird. Netbeans also dies if you use up all the threads.
我还注意到,如果我为 netbeans 打开分析工具(工具|分析)并从 ide 运行...我只能获得 400 个线程。奇怪的。如果您用完所有线程,Netbeans 也会死。
Here is a test app you can run:
这是您可以运行的测试应用程序:
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <signal.h>
// this prevents the compiler from reordering code over this COMPILER_BARRIER
// this doesnt do anything
#define COMPILER_BARRIER() __asm__ __volatile__ ("" ::: "memory")
sigset_t _fSigSet;
volatile int _cActive = 0;
pthread_t thrd[1000000];
void * thread(void *i)
{
int nSig, cActive;
cActive = __sync_fetch_and_add(&_cActive, 1);
COMPILER_BARRIER(); // make sure the active count is incremented before sigwait
// sigwait is a handy way to sleep a thread and wake it on command
sigwait(&_fSigSet, &nSig); //make the thread still alive
COMPILER_BARRIER(); // make sure the active count is decrimented after sigwait
cActive = __sync_fetch_and_add(&_cActive, -1);
//printf("%d(%d) ", i, cActive);
return 0;
}
int main(int argc, char** argv)
{
pthread_attr_t attr;
int cThreadRequest, cThreads, i, err, cActive, cbStack;
cbStack = (argc > 1) ? atoi(argv[1]) : 0x100000;
cThreadRequest = (argc > 2) ? atoi(argv[2]) : 30000;
sigemptyset(&_fSigSet);
sigaddset(&_fSigSet, SIGUSR1);
sigaddset(&_fSigSet, SIGSEGV);
printf("Start\n");
pthread_attr_init(&attr);
if ((err = pthread_attr_setstacksize(&attr, cbStack)) != 0)
printf("pthread_attr_setstacksize failed: err: %d %s\n", err, strerror(err));
for (i = 0; i < cThreadRequest; i++)
{
if ((err = pthread_create(&thrd[i], &attr, thread, (void*)i)) != 0)
{
printf("pthread_create failed on thread %d, error code: %d %s\n",
i, err, strerror(err));
break;
}
}
cThreads = i;
printf("\n");
// wait for threads to all be created, although we might not wait for
// all threads to make it through sigwait
while (1)
{
cActive = _cActive;
if (cActive == cThreads)
break;
printf("Waiting A %d/%d,", cActive, cThreads);
sched_yield();
}
// wake em all up so they exit
for (i = 0; i < cThreads; i++)
pthread_kill(thrd[i], SIGUSR1);
// wait for them all to exit, although we might be able to exit before
// the last thread returns
while (1)
{
cActive = _cActive;
if (!cActive)
break;
printf("Waiting B %d/%d,", cActive, cThreads);
sched_yield();
}
printf("\nDone. Threads requested: %d. Threads created: %d. StackSize=%lfmb\n",
cThreadRequest, cThreads, (double)cbStack/0x100000);
return 0;
}
回答by Mikko Rantalainen
There is a thread limit for linuxand it can be modified runtime by writing desired limit to /proc/sys/kernel/threads-max
. The default value is computed from the available system memory. In addition to that limit, there's also another limit: /proc/sys/vm/max_map_count
which limits the maximum mmapped segments and at least recent kernels will mmap memory per thread. It should be safe to increase that limit a lot if you hit it.
linux有一个线程限制,可以通过将所需限制写入/proc/sys/kernel/threads-max
. 默认值是根据可用系统内存计算得出的。除了这个限制之外,还有另一个限制:/proc/sys/vm/max_map_count
它限制了最大 mmapped 段,至少最近的内核将为每个线程 mmap 内存。如果您达到该限制,则增加该限制应该是安全的。
The limit you're hitting is lack of virtual memoryin 32bit operating system. Install a 64 bit linux if your hardware supports it and you'll be fine. I can easily start 30000 threads with a stack size of 8MB. The system has a single Core 2 Duo + 8 GB of system memory (I'm using 5 GB for other stuff in the same time) and it's running 64 bit Ubuntu with kernel 2.6.32. Note that memory overcommit (/proc/sys/vm/overcommit_memory) must be allowed because otherwise system would need at least 240 GB of committable memory (sum of real memory and swap space).
您遇到的限制是32 位操作系统中缺少虚拟内存。如果您的硬件支持,请安装 64 位 linux,您会没事的。我可以轻松启动 30000 个线程,堆栈大小为 8MB。该系统有一个 Core 2 Duo + 8 GB 系统内存(我同时将 5 GB 用于其他东西)并且它运行 64 位 Ubuntu,内核为 2.6.32。请注意,必须允许内存过量使用 (/proc/sys/vm/overcommit_memory),否则系统将需要至少 240 GB 的可提交内存(实内存和交换空间的总和)。
If you need lots of threads and cannot use 64 bit system your only choice is to minimize the memory usage per thread to conserve virtual memory. Start with requesting as little stack as you can live with.
如果您需要大量线程并且不能使用 64 位系统,您唯一的选择是最小化每个线程的内存使用量以节省虚拟内存。从请求尽可能少的堆栈开始。
回答by Ankit Singhal
I had also encountered the same problem when my number of threads crosses some threshold. It was because of the user level limit (number of process a user can run at a time) set to 1024 in /etc/security/limits.conf .
当我的线程数超过某个阈值时,我也遇到了同样的问题。这是因为 /etc/security/limits.conf 中的用户级别限制(用户一次可以运行的进程数)设置为 1024。
so check your /etc/security/limits.conf and look for entry:-
因此,请检查您的 /etc/security/limits.conf 并查找条目:-
username -/soft/hard -nproc 1024
用户名-/软/硬-nproc 1024
change it to some larger values to something 100k(requires sudo privileges/root) and it should work for you.
将其更改为一些更大的值到 100k(需要 sudo 权限/root),它应该适合你。
To learn more about security policy ,see http://linux.die.net/man/5/limits.conf.
要了解有关安全策略的更多信息,请参阅http://linux.die.net/man/5/limits.conf。
回答by Axel Podehl
check the stack size per thread with ulimit, in my case Redhat Linux 2.6:
使用 ulimit 检查每个线程的堆栈大小,在我的情况下是 Redhat Linux 2.6:
ulimit -a
...
stack size (kbytes, -s) 10240
Each of your threads will get this amount of memory (10MB) assigned for it's stack. With a 32bit program and a maximum address space of 4GB, that is a maximum of only 4096MB / 10MB = 409 threads !!! Minus program code, minus heap-space will probably lead to your observed max. of 300 threads.
您的每个线程都将获得分配给它的堆栈的内存量 (10MB)。使用 32 位程序和 4GB 的最大地址空间,最多只有 4096MB / 10MB = 409 个线程!!!减去程序代码,减去堆空间可能会导致您观察到的最大值。300 个线程。
You should be able to raise this by compiling a 64bit application or setting ulimit -s 8192 or even ulimit -s 4096. But if this is advisable is another discussion...
您应该能够通过编译 64 位应用程序或设置 ulimit -s 8192 甚至 ulimit -s 4096 来解决此问题。但如果这是可取的,则是另一个讨论...