现在的位置: 首页 > 综合 > 正文

进程栈大小 与 线程栈大小

2013年06月16日 ⁄ 综合 ⁄ 共 1913字 ⁄ 字号 评论关闭

我在FC3,gcc3.4.2环境下进行该实验,证明线程的栈确实有固定大小,也就是ulimit -a显示的那个值,在我的实验室环境下为10M字节 
实验1: 
#include <stdio.h> 
#include <pthread.h> 

int i = 0; 

void *test(void * s) { 
int buffer[1024]; 
printf("i=%d\n", i); 
i++; 
test(s); 


int main() { 
pthread_t p; 

pthread_create(&p, NULL, &test, NULL); 
sleep(100); 



并且可以使用如下代码修改这个线程栈的大小为16M: 
实验2: 
#include <stdio.h> 
#include <pthread.h> 

int i = 0; 

void *test(void * s) { 
int buffer[1024]; 
printf("i=%d\n", i); 
i++; 
test(s); 


int main() { 
pthread_t p; 
pthread_attr_t tattr; 
void *stack; 

pthread_attr_init(&tattr); 

stack=malloc(16*1024*1024); 
pthread_attr_setstack(&tattr,stack,16*1024*1024); //注意这个空间应该从堆中分配,如果从栈中分配,就会出现另一个问题,我们后面会提到 
pthread_create(&p, &tattr, &test, NULL); 
sleep(100); 


但是如果用两个线程使用默认大小,来进行上面的实验,两个栈的总和并不是一个线程的二倍,并且这个总和也不是固定值 
实验3: 
#include <stdio.h> 
#include <pthread.h> 

int i = 0; 
pthread_mutex_t mutex=PTHREAD_MUTEX_INITIALIZER; 

void *test(void * s) { 
int buffer[1024]; 
pthread_mutex_lock(&mutex); 
printf("i=%d\n", i); 
i++; 
pthread_mutex_unlock(&mutex); 
test(s); 


int main() { 
pthread_t p1,p2; 
pthread_create(&p1, NULL, &test, NULL); 
pthread_create(&p2, NULL, test, NULL); 
sleep(100); 


如果不使用任何线程的话,那么一个进程的栈也不是理论上的2G,而是比一个线程的栈稍(ulimit -a 的值10M)大一些,并且这个栈的大小也不总是固定的 
实验4: 
#include <stdio.h> 

int i=0; 

void fun() 

int buffer[1024]; 
printf("i=%d\n",i); 
i++; 
fun(); 


int main() 

fun(); 
sleep(100); 


如果pthread_attr_setstack设置的线程栈是从栈空间分配的话,如果线程栈的大小为10M的话,那么线程栈的大小也不是固定不变了而是和实验4的结果相同(类似?) 
如果线程栈大小为11M的话,那么线程栈的大小也不是固定不变,但这个时候有可能在进程一开始的时候就发生段错误,即使是同一个可执行文件多次不同执行也会出现这种现象,说明这个栈的大小是和gcc的编译与链接无关的 

实验5: 
#include <stdio.h> 
#include <pthread.h> 

int i = 0; 

void *test(void * s) { 
int buffer[1024]; 
printf("i=%d\n", i); 
i++; 
test(s); 


int main() { 
pthread_t p; 
pthread_attr_t tattr; 
char stack[11*1024*1024]; 

pthread_attr_init(&tattr); 

pthread_attr_setstack(&tattr,&stack[0],11*1024*1024); 
pthread_create(&p, &tattr, &test, NULL); 
sleep(100); 



结论: 
1. 进程的栈大小是在进程执行的时刻才能指定的,即不是在编译的时刻决定,也不是链接的时刻决定,否则就不会有实验5的结果 
2. 进程的栈大小是随机确定的至少比线程的栈要大,但是不到线程栈大小的2倍 
3. 线程栈的大小是固定的,也就是ulimit -a显示的值

抱歉!评论已关闭.