17、深入理解電腦系統筆記:非本地跳轉

來源:互聯網
上載者:User

1、C提供了使用者級異常控制流程,稱為非本地跳轉(nonlocal jump),它將控制流程從一個函數轉移到另一個當前正在執行的函數;而不需要經過正常的調用-返回序列。通過setjmp和longjmp來實現的。

函數原形

#include <setjmp.h>int setjmp(jmp buf env);int sigsetjmp(sigjmp buf env, int savesigs); //訊號版本returns: 0 from setjmp, nonzero from longjmps)#include <setjmp.h>void longjmp(jmp buf env, int retval);void siglongjmp(sigjmp buf env, int retval); //訊號版本never returns)

C++提供的異常機制是高層次的,是C的setjmp,longjmp函數的更加結構化的版本。可把try語句中的catch子句看作是setjmp函數的類似物;throw語句類似於longjmp函數。

The setjmp function saves the current stack context in the env buffer, for later

use by longjmp。The longjmp function restores the stack context from the env buffer

and then triggers a return from the most recent setjmp call that initialized env. The

setjmp then returns with the nonzero return value retval.

The setjmp function is called once but returns multiple times: once when the

setjmp is first called and the stack context is stored in the env buffer, and once for

each corresponding longjmp call. On the other hand, the longjmp function is called

once but never returns。

2、應用

1)允許從一個深層嵌套的函數調用中立即返回,通常是由檢測到錯誤引起的。

範例程式碼

/* $begin setjmp */#include "csapp.h"jmp_buf buf;int error1 = 0; int error2 = 1;void foo(void), bar(void);int main() {    int rc;rc = setjmp(buf);/*The main routine first calls setjmp to save the current stack context*/    if (rc == 0)foo();    else if (rc == 1) printf("Detected an error1 condition in foo\n");    else if (rc == 2) printf("Detected an error2 condition in foo\n");    else printf("Unknown error condition in foo\n");    exit(0);}/* deeply nested function foo */void foo(void) {    if (error1)longjmp(buf, 1);     bar();}void bar(void) {    if (error2)longjmp(buf, 2); }/* $end setjmp */

2)使一個訊號處理常式分支到一個特殊的代碼位置,而不是返回到被訊號到達中斷了的位置。

範例程式碼

/* $begin restart */#include "csapp.h"sigjmp_buf buf;void handler(int sig) {    siglongjmp(buf, 1);}int main() {    Signal(SIGINT, handler);if (!sigsetjmp(buf, 1)) /*The initial call to the sigsetjmp function saves the stack and signal context when the program first starts.*/printf("starting\n");    else printf("restarting\n");    while(1) {Sleep(1);printf("processing...\n");    }    exit(0);}/* $end restart *//*The program uses signals and nonlocal jumps to do a soft restart whenever the user types ctrl-c at the keyboard.當捕獲到SIGINT訊號時,不是從訊號處理常式返回到被中斷的處理迴圈,而是跳轉到the beginning of the main program.*/

<Computer Systems:A Programmer's Perspective>

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.