《深入理解計算機系統》第八章 (五)非本地跳轉 setjmp longjmp

/* $begin restart */
#include "csapp.h"

sigjmp_buf buf;

void handler(int sig)
{
    siglongjmp(buf, 1);
}

int main()
{
    Signal(SIGINT, handler);

    if (!sigsetjmp(buf, 1))
    printf("starting\n");
    else
    printf("restarting\n");

    while(1) {
    Sleep(1);
    printf("processing...\n");
    }
    exit(0);
}
/* $end restart */

setjmp函數

#include <setjmp.h>

int setjmp(jmp_buf env);

int sigsetjmp(sigjmp_buf env, int savesigs);

setjmp函數在env緩衝區中保存當前調用環境,以供後面的longjmp使用,並返回0。調用環境包括程序計數器、棧指針和通用目的寄存器。


longjmp函數

 #include <setjmp.h>

void longjmp(jmp_buf env, int val);

void siglongjmp(sigjmp_buf env, int val);

longjmp函數從env緩衝區中恢復調用環境,然後觸發一個從最近一次初始化env的setjmp調用的返回。


核心要點:

setjmp函數之被調用一次,但返回多次,一次是當第一次調用setjmp,而調用環境保存在緩衝區env中時;一次是爲每個相應的longjmp調用。

longjmp函數被調用一次,但從不返回。


非本地返回的意義:

非本地返回的一個重要意義在於允許從一個深層嵌套的函數中立即返回,而不用費力解開調用棧。


例程分析:

setjmp在第一次被調用的時候返回0 ,打印出”starting“

之後如果按下ctrl+c就會發送SIGINT信號,進程接收到該信號後就會調用信號處理程序,信號處理程序執行longjmp,觸發setjmp返回,返回值爲val,即爲1,則進程打印輸出restarting。之後繼續跳入while循環。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章