在嵌入式系统中,为了减少内存的占用,有时候需要设置线程的 stack 大小(因为默认的大小过大)。
下面这段代码首先读出系统默认的stack 大小,然后重新设置一个大小,再重新读出来。
#include <pthread.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
void *foo(void *arg)
{
int size = 0;
pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_attr_getstacksize(&attr, &size);
printf("get stack size : %dK\n", size/1024);
return 0;
}
int main(int argc, char ** argv)
{
pthread_t id = -1;
pthread_attr_t attr;
int size = 0;
if(argc != 2)
{
return -1;
}
pthread_attr_init(&attr);
pthread_attr_getstacksize(&attr, &size);
printf("the default pthread stack size: %dK\n", size/1024);
size = atoi(argv[1]);
if( pthread_attr_setstacksize(&attr, size) != 0)
{
int err =errno;
// printf("set stack size error: %dK, (%d) (%s)\n", size/1024, err, strerror(err));
printf("set stack size error\n");
}
pthread_create(&id, &attr, foo, NULL);
pthread_join(id, NULL);
pthread_attr_destroy(&attr);
return 0;
}
执行命令 gcc -g -pthread getstacksize.c -lpthread
,然后,试着输入几个stack size:
$ ./a.out 1024
the default pthread stack size: 8192K
set stack size error
get stack size : 8192K
charles@taotao:~$ ./a.out 262144
the default pthread stack size: 8192K
get stack size : 8192K
charles@taotao:~$ ./a.out 2097152
the default pthread stack size: 8192K
get stack size : 8192K
第一次设置 1024 (1K)失败,stack size为默认的 8M (8192K).
第二次设置 262144(256K)成功,但是 stack size还是 8M.
第三次同样。
为什么设置的stack size没有正确返回呢?
今天重新看了下这个问题,发现是对函数 pthread_attr_init()的使用有问题。
这个函数会对传入的 pthread_attr_t变量初始化,其中会把 stack size设为0.
而 pthread_attr_getstacksize函数会判断 传入的 attr的stack size,如果为0,使用系统默认的stack size.
int
__pthread_attr_getstacksize (attr, stacksize)
const pthread_attr_t *attr;
size_t *stacksize;
{
struct pthread_attr *iattr;
assert (sizeof (*attr) >= sizeof (struct pthread_attr));
iattr = (struct pthread_attr *) attr;
size_t size = iattr->stacksize;
/* If the user has not set a stack size we return what the system
will use as the default. */
if (size == 0)
{
lll_lock (__default_pthread_attr_lock, LLL_PRIVATE);
size = __default_pthread_attr.stacksize;
lll_unlock (__default_pthread_attr_lock, LLL_PRIVATE);
}
*stacksize = size;
return 0;
}