除非您缩小默认线程堆栈大小,否则您也会耗尽内存。 在我们的Linux版本中,它为10MB。
编辑:
错误代码12 = 内存不足,因此我认为1MB堆栈对您来说仍然太大了。 编译为32位时,我可以获得100k堆栈以给我30k个线程。 超过30k个线程,我会收到错误代码11,这意味着不允许更多线程。 1MB堆栈在出现错误代码12之前给我约4k个线程。 10MB给我427个线程。 100MB给我42个线程。 1GB给我4个... 我们有64位操作系统和64 GB RAM。 您的操作系统是32位吗? 当我编译为64位时,我可以使用任何堆栈大小并获得线程限制。
另外,我注意到如果我打开NetBeans的分析工具(工具|分析)并从IDE运行...我只能获得400个线程。 奇怪。 如果使用所有线程,NetBeans也会崩溃。
这是一个您可以运行的测试应用程序:
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <signal.h>
#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();
sigwait(&_fSigSet, &nSig);
COMPILER_BARRIER();
cActive = __sync_fetch_and_add(&_cActive, -1);
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");
while (1)
{
cActive = _cActive;
if (cActive == cThreads)
break;
printf("Waiting A %d/%d,", cActive, cThreads);
sched_yield();
}
for (i = 0; i < cThreads; i++)
pthread_kill(thrd[i], SIGUSR1);
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;
}