1. 程式人生 > >程序棧大小 與 執行緒棧大小-轉

程序棧大小 與 執行緒棧大小-轉

我在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顯示的值