我只是在64位SLES linux上测试pthread_attr_getstacksize()的用法。
#include <stdio.h>
#include <limits.h>
#include <errno.h>
#include <stdlib.h>
#include<string.h>
#include <sys/file.h>
#include <sys/mman.h>
#include <sys/wait.h>
#include <pthread.h>
void* doSomeThing(void *arg)
{
unsigned long i = 0;
pthread_t id = pthread_self();
printf(">>> id = 0x%x\n", id);
for(i=0; i<(0xFFFFFFFF);i++);
return NULL;
}
main(int argc, char* argv[])
{
pthread_attr_t pattr;
pthread_t thread;
int error = 0;
size_t ssize=0;
error = pthread_attr_init(&pattr);
if(error)
goto Return;
error = pthread_attr_setdetachstate(&pattr, PTHREAD_CREATE_DETACHED);
if (error)
goto Return;
error = pthread_attr_getstacksize(&pattr , &ssize);
printf(" >>> ssize = %u\n", ssize);
error = pthread_create(&thread, &pattr, &doSomeThing, NULL);
if(error != 0)
{
printf("\ncan't create thread :[%s]", strerror(error));
}
else
{
printf("\n Thread created successfully\n");
}
Return:
return(0);
}
它给了我不同的堆栈大小,如114500742,2025756486,4147952480不同的时间。 为什么堆栈大小会发生变化?
ulimit -a也显示
# ulimit -a
...
max locked memory (kbytes, -l) 64
max memory size (kbytes, -m) 1635484
...
stack size (kbytes, -s) 8192
...
max user processes (-u) 14942
virtual memory (kbytes, -v) 1539280
当ulimit显示堆栈大小为8 MB时,为什么pthread_attr_getstacksize()以GB为单位返回堆栈大小?
堆栈大小很大,所以我无法创建超过186个线程,因为pthread_create失败并出现错误12(ENOMEM)。
答案 0 :(得分:1)
它给了我不同的堆栈大小,如114500742,2025756486,4147952480不同的时间。为什么堆栈大小会发生变化?
我认为这是您操作系统中的一个错误。
从我以前使用各种* nix系统(Solaris,AIX,HP-UX),Debian / Ubuntu,SLES10和RHEL5进行的实验,默认堆栈大小(您查询和打印)是稳定的,并且没有在运行之间波动。
我看到的唯一大小变化与32位相对应的64位构建相关。正如所料,对于64位应用程序,默认的线程堆栈大小比32位应用程序大。
当ulimit显示堆栈大小为8 MB时,为什么pthread_attr_getstacksize()以GB为单位返回堆栈大小?
ulimit
显示主线程的堆栈大小,而不是线程堆栈大小。
主堆栈(由调用main()
的线程使用)是特殊的,因为它是由内核创建的,在更高的内存地址分配,理论上它甚至可以增长到堆的结尾(brk()
返回的值)。
相反,线程堆栈由应用程序本身分配,甚至可以在堆中分配(尽管通常使用匿名mmap()
)。它没有被特别处理:它是一个普通的内存块,无论如何分配,在线程终止后应用程序将释放它。
堆栈大小很大,所以我无法创建超过186个线程,因为pthread_create失败并出现错误12(ENOMEM)。
将问题报告给SUSE。
使用pthread_attr_setstacksize()
在应用程序中明确设置大小。大多数* nix系统的默认线程堆栈大小约为256-512K,Solaris - 2MB,Ubuntu - 8MB。对于许多应用程序来说,512K就足够了,但是如果你的应用程序在堆栈上放置大型结构/数组,那么8MB将是一个更安全的值。