關於線程堆棧大小的注意事項


    今天在給車綜的SDK做測試時,遇到了一個線程崩潰的問題。大概情形是我 用車綜的SDK封裝了一個類,在一個線程中定義了一個這個類的對象,然后再線程啟動的時候,在線程的入口處即導致崩潰。然而以指針的形式來定義則沒有問題。經大神指出是因為每個線程對於所使用的堆棧大小是有限制的,我的這個類對象占用的堆棧超出了限制。

    以下資料參考博客關於線程堆棧大小的注意事項 

每個線程獨立擁有一個可配置大小的堆棧,一個線程內所有函數使用到的堆棧都依賴於這個棧,如果太多的變量、參數需要使用棧,則可能導致棧溢出。目前基礎平台子系統通過配置環境變量,將默認堆棧大小設置為128K,可以減少這個問題的出現,但業務系統在編碼時仍然 需要注意棧的使用,避免出現問題。

    包括:
    1、不要在函數內部定義過大的局部變量,如過大的結構體變量,聯合變量,過大的字符串,數組等;
    2、函數調用的深度也需要注意,如果函數 A 調用 B, B 再調用 C,而A/B/C每個函數定義了 10 K的局部變量,則總的棧空間需求將超過 30K;
    3、不要直接將大的結構變量通過函數參數傳遞,這樣也會消耗棧空間,可以通過指針或者引用的方式傳遞;
    4、建議每個函數內部定義的變量大小控制在4-8K以下;
    5、如果在運行中 COREDUMP,並且通過 GDB 的 WHERE 命令時看到剛進入某個函數就報錯,連函數內的第一條調試語句都無法指向,則基本可以認為是棧空間不夠導致的,可以嘗試將棧空間配置大一點,如果問題不再出現,則可以確定問題。這時需要按照前面幾點的要求修改代碼,減少棧的使用。


這讓我想起了之前在做英偉達硬解時,在線程內分配顯存會導致崩潰,而把分配顯存移到線程外則沒有問題。大神猜測說是線程對顯存的分配有限制。   在此一並記錄。


另一篇關於修改線程堆棧大小博客設置線程堆棧大小


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM