2011-08-28 112 views
2

爲什麼setjmp不保存堆棧?
考慮下面的代碼:爲什麼setjmp不能保存堆棧?

#include <iostream> 

jmp_buf Buf; 
jmp_buf Buf2; 

void MyFunction() 
{ 
    for(int i = 0; i < 5; i++) 
    { 
     std::cout << i << std::endl; 
     if(!setjmp(Buf)) 
      longjmp(Buf2, 1); 
    } 
} 

int main (int argc, const char * argv[]) 
{ 
    while(true) 
    { 
     if(!setjmp(Buf2)) 
     { 
      MyFunction(); 
      break; 
     } 
     longjmp(Buf, 1); 
    } 
    return 0; 
} 

我除了是代碼將跳轉從主來回功能,每次回來印刷越來越多。
實際發生的是它無限次地打印0然後1。就好像它跳回到函數棧中重置爲默認值一樣。它爲什麼這樣做?有什麼辦法可以讓它保存堆棧嗎?
我知道setjmplongjmp在編碼風格和可讀代碼方面比goto更差,但我現在正在試驗,而且這段代碼可能永遠不會看到可用應用程序的燈光。

回答

2

因爲不幸的是,那不是setjmp如何工作。 setjmp將當前指令指針和寄存器組拷貝到跳轉緩衝區中,但它不會複製堆棧(顯然會導致堆棧很大)。看起來你想使用某種基於協程的技術。如果你想自己做這個檢查ucontext procedured(ucontext.h)http://compute.cnr.berkeley.edu/cgi-bin/man-cgi?ucontext.h+3他們將幫助你分配和管理additionaly線程堆棧。

或者你可以使用像Russ Cox的libtask(http://swtch.com/libtask/)這樣可以幫助你做到這一點。或者如果你想自己做,你應該看看libtask代碼(也可以通過該鏈接獲得)。它很容易閱讀,所以它是一個很好的資源。