2009-12-04 120 views
1

我正在開發使用C編程語言的多線程模塊化應用程序和NPTL 2.6。對於每個插件,都會創建一個POSIX線程。問題是每個線程都有自己的堆棧區域,因爲默認的堆棧大小取決於用戶的選擇,在某些情況下這可能會導致大量的內存消耗。NPTL默認堆棧大小問題

爲了避免不必要的內存使用我用類似於這樣創建每個線程之前改變堆棧大小:加入在pthread_create()部分:

pthread_attr_t attr; 
pthread_attr_init (&attr); 
pthread_attr_getstacksize(&attr, &st1); 
if(pthread_attr_setstacksize (&attr, MODULE_THREAD_SIZE) != 0) perror("Stack ERR"); 
pthread_attr_getstacksize(&attr, &st2); 
printf("OLD:%d, NEW:%d - MIN: %d\n", st1, st2, PTHREAD_STACK_MIN); 
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 
/* "this" is static data structure that stores plugin related data */ 
pthread_create(&this->runner, &attr, (void *)(void *)this->run, NULL); 

編輯我。

此沒有工作的工作如我所料,通過pthread_attr_getstacksize()報告的堆棧大小被改變,但應用(從PS /頂部/ PMAP輸出)的總的內存使用情況沒有改變:

OLD:10485760 ,NEW:65536 - MIN:16384

當我在啓動應用程序之前使用ulimit -s MY_STACK_SIZE_LIMIT時,我達到了預期的結果。

我的問題是:

1)是否有任何便攜式(間UNIX變體)的方法來改變啓動應用程序(當然創建線程)之前後(默認)線程堆棧大小?

2-)是否可以爲每個線程使用相同的堆棧區域?

3-)是否有可能完全禁用堆棧的線程沒有太大的痛苦?

+0

愚蠢的問題,但是當你通過'pthread_attr_setstacksize()'修改了堆棧大小後,你是否在實際創建線程時使用了'attr'?我們可以看看你如何調用'pthread_create()'? – 2009-12-04 08:05:09

+0

當然,我已更新我的帖子。 – 2009-12-04 08:30:11

回答

2

#2和#3的答案是否定的。每個線程都需要一個堆棧(你的本地變量和返回地址去哪裏?),它們需要是每個線程唯一的(否則線程會覆蓋彼此的局部變量並返回地址,使每個人都崩潰)。

至於#1 ...設置的堆棧大小調用正是這個答案。我建議你找出一個可接受的大小來創建你的線程,並設置它。

至於爲什麼事情看起來不對你在top .... top是一個臭名昭着的關於內存使用情況的騙子。 :-)是否有東西實際上沒有被分配或被OOM殺死?線程創作失敗了嗎?性能是否受到影響並且正在向磁盤分頁?如果對這些問題的答案是否定的,那麼我認爲不必擔心太多。

根據以下和部分評論進行更新:
首先,16KB對於您認爲不需要太多堆棧空間的東西來說還是相當大的。如果你真的想要變小,我會試圖在x86 Linux上說4096或8192。其次,是的,你可以將CPU的堆棧指針設置爲其他值。但是當你使用malloc()mmap()時,這將佔用空間。我不知道你認爲它會如何幫助將堆棧指針設置爲別的。也就是說,如果你真的強烈感覺到main()的線程太大(我會說這有點瘋狂),並且pthread_attr_setstacksize()不會讓你變得足夠小(?),那麼也許你可以看看通過調用clone()系統調用並根據主線程的堆棧指針或來自其他地方的緩衝區指定堆棧,或類似的東西來創建線程等非便攜式東西。但你仍然需要爲每個線程堆棧,我有一種感覺top仍然會讓你失望。也許你的期望有點高。

+0

這正是他正在做的,請查看他的消息來源的第2行! – Puppe 2009-12-04 06:24:31

+0

是的Puppe,這正是我正在做的。即使堆棧大小可以接受,它也不像我預期的那樣工作。至於Q3,我確信有第三方庫可以禁用堆棧甚至進程。所以應該有一種方法來模擬堆上的堆棧。 – 2009-12-04 06:35:10

+0

@eyazici - 好吧,堆棧指針是一個CPU寄存器,你可以將它設置爲任何你想要的,包括你從malloc()或mmap()得到的東西。但是從你的問題來看,我不知道你在問什麼 - 嘿,即使你從其他地方得到它,它仍然是一個堆棧,它仍然會消耗內存等。 – asveikau 2009-12-04 06:37:14

1

我也看到了這個問題。目前還不清楚堆棧是如何計算的,但是「額外」空間是針對您的總虛擬機計算的,並且如果您遇到過程邊界時遇到問題(即使您未使用該空間)。它看起來取決於你正在運行的Linux版本(甚至在2.6系列中),以及你是32位還是64位。

+0

它是32位CentOS版本5.3,內核2.6.18 – 2010-05-16 16:29:56