プロセス間通信-システム呼び出しsetjmp()とlongjmp()


システム呼び出しsetjmp()とlongjmp()
場合によっては、信号を受信すると、プログラム内の以前の位置に戻って実行したい場合がある.例えば、あるプログラム内で、ユーザが割り込みキーを押すと、プログラムは表示メインメニューに戻って実行される.ライブラリシステムでsetjmp()とlongjmp()を呼び出してこの作業を完了できます.setjmp()はプログラム内の現在位置(スタック環境を保存することによって実現される)を保存することができ、longjmp()は制御を保存された位置に戻すことができる.ある意味でlongjmp()は、ローカル領域内のジャンプではなく、リモートジャンプである.スタックが保存された位置に戻ったためlongjmp()は戻ってこないことに注意しなければならない.ただし、それに対応するsetjmp()は返されます.
setjmp()とlongjmp()はsetjmp.hの定義はそれぞれ以下の通りである.
int setjmp(jmp_buf env);
void longjmp(jmp_buf env, int val);

setjmp()には、プログラムの現在の場所のスタック環境を保存するためのパラメータenvが1つしかありません.longjmp()には2つのパラメータがあります.
  • パラメータenvはsetjmp()によって保存されるスタック環境である.
  • パラメータval setjmp()の戻り値を設定します.
  • longjmp()自体は返されませんが、実行後にenvパラメータを保存するsetjmp()呼び出しにジャンプし、setjmp()呼び出しによって返されます.プログラムがsetjmp()を実行したばかりのように、setjmp()の戻り値がvalになります.ただし、longjmp()呼び出しではsetjmp()呼び出しを0に戻すことはできません.valが0の場合、setjmp()の戻りは1になります.
    次の例では、setjmp()とlongjmp()の使用を示します.
    #include <stdio.h>
    #include <setjmp.h>
    #include <signal.h>
    jmp_buf position;
    main(){
    int goback();
    …
    …
    /*            */
    setjmp(position);
    signal(SIGINT,goback);
    domenu();
    …
    …
    }
    goback()
    {
    fprintf(stderr,” 
    Interrupted
    ” ); /* */ longjmp(position,1); }

    参考資料:
    『linuxネットワークプログラミング』李卓恒等訳