程序棧大小 與 執行緒棧大小-轉
阿新 • • 發佈:2019-02-09
我在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顯示的值