Chinaunix首页 | 论坛 | 博客

fx

  • 博客访问: 1372484
  • 博文数量: 115
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 3964
  • 用 户 组: 普通用户
  • 注册时间: 2013-05-02 14:36
文章分类
文章存档

2022年(2)

2019年(2)

2018年(10)

2017年(1)

2016年(50)

2015年(12)

2014年(9)

2013年(29)

分类: LINUX

2013-06-07 14:58:10

接着上篇:

下面三个是与线程栈有关的属性:

线程栈末尾的境界缓冲区大小
线程栈的最低地址
线程栈的大小
通常我们需要修改一般只有线程栈的大小

对于进程来说,虚拟地址空间大小是固定的,进程中只有一个栈。所以他的大小通常不是问题
对线程来说过,同样大小的虚拟地址空间必须被所有的线程共享,如果线程太多导致超过可用的
虚拟地址空间,这时就需要减少线程默认的线程栈大小。同样如果一个线程需要使用很多的自动变量
或涉及很深层次的函数调用,那么就需要调整增大默认线程栈大小

下面是他们的接口:
int pthread_attr_getstack(const pthread_attr_t *restrict attr,void **restrict stackaddr,size_t *restrict stacksize);

int pthread_attr_setstack(pthread_attr_t *attr,void *stackaddr,size_t *stacksize);
这两个函数可以用来管理 stackaddr线程属性,也可以用来管理stacksize线程属性


如果仅仅想改变线程栈的大小,但自己不想处理线程栈的分配问题。

下面这两个函数提供了一个只修改线程栈大小的简单接口
int pthread_attr_getstacksize(const pthread_attr_t *restrict attr,
size_t *restrict stacksize);
int pthread_atty_setstacksize(pthread_attr_t *attr,size_t stacksize);


线程guardsize属性控制着线程栈末尾之后用以避免栈溢出的扩展内存的大小。
提供的函数如下:
int pthread_attr_getguardsize(const pthread_attr_t *restrict attr,
size_t *restrict guatdsize);
int pthread_attr_setguardsize(pthread_attr_t *attr,size_t guardsize);

针对上面三个关于线程栈方面的线程属性,下面对线程栈大小作了一个测试

程序中有两个函数f1,f2这两个函数是循环调用的,他们都调用对方,并输出是多少次调用。我们用这种方式来测试栈大小

void f1(void);
void f2(void);
int i=0;;

void *th1(void *arg){
f1();
pthread_exit((void *)0);
}
void f1(void){
i++;
printf("i=%d\n",i);
f2();
}
void f2(void){
i++;
printf("i=%d\n",i);
f1();
}
int main(void){
pthread_t tid;
pthread_attr_t attr;

int err;
err=pthread_attr_init(&attr);
if(err!=0){
printf("initialization attribute error:%s\n",strerror(err));
exit(1);
}
size_t stack_size;
pthread_attr_getstacksize(&attr,&stack_size);
printf("stack size:%u\n",stack_size);

36 // stack_size=100000;
if((err=pthread_attr_setstacksize(&attr,stack_size))!=0){
printf("error:%s\n",strerror(err));
exit(1);
}
pthread_attr_getstacksize(&attr,&stack_size);
printf("Now:\n");
printf("stack size:%u\n",stack_size);

err=pthread_create(&tid,&attr,th1,(void *)0);
if(err!=0){
printf("create new thread error:%s\n",strerror(err));
exit(1);
}
pthread_attr_destroy(&attr);
pthread_join(tid,NULL);
exit(0);
}

程序中 第三十六行被注释掉了,那么我们是以默认线程栈大小创建线程的
程序的截取输出如下:
。。。
。。。
。。。
i=261983
i=261984
i=261985
i=261986
i=261987
Segmentation fault (core dumped)
也就是 差不多 261987次左右的函数循环调用后就用完栈了。(可以把低14行和第19行的输出去掉,
从程序输出中就能看到默认栈大小为8688608,不过不同的系统可能也不一样)

现在去掉第十九行的注释,吧栈大小设置为100000然后再次运行:
。。。
。。。
。。。
i=2836
i=2837
i=2838
i=2839
Segmentation fault (core dumped)
从输出可以明显看到循环调用的次数变小很多。

注意不能把栈的大小设置的太小。如果把栈的大小设置的很小,那么pthread_attr_setstacksize调用会失败,返回的
错误码为 :无效值

比如吧36行
stack_size=100000;
改为stack_size=10000;
那么运行输出:
stack size:8388608 //这个是线程默认的线程栈大小
error:Invalid argument

阅读(2248) | 评论(1) | 转发(0) |
给主人留下些什么吧!~~