2

操作系統如何確定將在底層進程的地址空間中爲每個線程提供多少堆棧空間?操作系統如何確定應爲每個線程分配多少堆棧空間?

如果一個線程最初使用分配給它的所有堆棧空間,並且同一進程的其他線程存在大量未充分利用的空間,那該怎麼辦? 我明白,堆棧和堆堆棧和堆堆排序相同的問題可以通過兩者相反的方向來解決。

操作系統是否在內存的其他地方爲線程分配了更多的空間,還是會導致堆棧溢出?

+2

線程耗盡堆棧時會發生什麼?答案在你的問題之上。 –

+0

但是如果進程的地址空間中的其他線程有很多未充分利用的空間會怎麼樣,它會不會導致堆棧溢出? – amiageek

+1

是的。每個線程的堆棧是獨立的,獨立於其他線程堆棧。盯着它們一般來說是一個非常糟糕的主意。 –

回答

4

這不是由操作系統來決定的,它是一個程序員的工作。以Windows爲例,第一個線程(即OS啓動的線程)的堆棧大小在可執行文件頭中指定。 IMAGE_OPTIONAL_HEADER.SizeOfStackReserve設置大小。它將壓縮文件傳遞到生成頭文件的任何工具,例如鏈接器,您可以使用它的/STACK option來設置大小。

大多數構建工具將使用合理的默認大小,保留大小的一兆字節非常常見,初始提交大小爲4096(一頁)。或者沒有那麼合理的默認值,.NET程序會提前整個堆棧空間。

這還需要在啓動線程時指定,像CreateThread這樣的winapi函數需要參數來設置大小。默認值是可用的,如果您指定0,則OS使用EXE頭中指定的大小。這是非常普遍的,實際大小很少是關鍵的,因爲大多數程序會嚴重超大堆棧。重要的是要遠離災難。請注意,在需求分頁的操作系統上,超大堆棧不會花費任何費用,您只需支付所使用的費用。

在很多情況下,堆棧空間不足都是不可恢復的錯誤,處理器無法再打電話。這個網站的名字的原因。還有其他線程不會消耗整個堆棧,這是不相關的,切換堆棧通常不起作用。程序使用指向堆棧空間的指針,您無法找到它們來更新值。

+0

這是否意味着如果一個線程利用了程序員希望它具有的缺省堆棧空間並超出該空間,下一個線程的堆棧空間就會啓動,程序會給我一個堆棧溢出,或者這個堆棧可以交換從存儲器中的當前位置移出,並在對虛擬存儲器映射進行更改之後,將其存儲在內存空間可用的其他位置? – amiageek

+2

提問並回答。你需要停止假設「交換」可以工作。它不能。學習C語言是瞭解機器的好方法。 –

相關問題