查找线程堆栈大小

时间:2015-05-11 20:41:48

标签: c multithreading pthreads

我只是在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)。

1 个答案:

答案 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将是一个更安全的值。