プロセスの終了、環境テーブル、メモリ内のレイアウト、および非ローカルジャンプ

プロセスの終了方法、環境テーブルの操作、メモリ内のレイアウト、および非ローカルジャンプ

プロセスID:
すべてのLinuxプロセスには、プロセスID(常に負でない整数)と呼ばれる一意の数値識別子が必要です。

プロセスの終了:
通常の終了:
1。メインからの戻り(戻り)2。exitの呼び出し
(標準ライブラリ)
3。_exitまたは_Exitの呼び出し(カーネルによって提供)
4。最後のスレッドが起動ルーチンから戻ります
5.最後のスレッドが呼び出しますpthread_exit
異常終了:
abort(シグナル関連)を呼び出し
てシグナル受信し、
最後のスレッドを終了(シグナル関連)して対応する
exitを実行し、キャンセル要求に対して_exit()呼び出して、バッファー領域の
フラッシュI / Oatexit関数をフラッシュするかどうかを区別し
ます。

exit:最初にバッファ領域を更新してから、プロセスを終了します。終了する前に、シグナル登録関数atexit _exitを呼び出します。バッファ領域を更新
せずにプロセスを直接終了します。カーネルは、atexitを渡さずにプロセスを直接終了します。

exit.c

#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <string.h> #include <errno.h> int main(int argc、char * argv []){if( argc <3){ 
        fprintf(stderr、 "usage:%s file return | exit | _exit \ n"、argv [0]); 
        exit(1); 
    }

    ファイル* fp = fopen(argv [1]、 "w"); //双引号char * str = "hellophp"; 

    fprintf(fp、 "%s"、str); if(!strcmp(argv [2]、 "return")){return 0; 
    } else if(!strcmp(argv [2]、 "exit")){ 
        exit(0); 
    } else if(!strcmp(argv [2]、 "_ exit")){_ exit 
        (0); 
    } else { 
        printf( "プロセスエラー\ n"); 
    } return 0; 
}

運転結果

[root @ centos1 exit]#。/ a.out exit.txt exit 
[root @ centos1 exit]#。/ a.out _exit.txt _exit 
[root @ centos1 exit]#。/ a.out return.txt return 
[root @ centos1出口]#以上* .txtの
:::::::::::::: 
_exit.txt 
:::::::::::::: 
:::::::::: :::: 
exit.txt 
:::::::::::::: 
hellophp 
:::::::::::::: 
return.txt 
::::::::::: :::
hellophp

プロセス環境テーブル

現在のプロセスの環境テーブルを取得します
1.他の場所で定義されている導入を通じて
 externchar ** environment 2.main
の3番目のパラメーターを通じて

インプロセス環境テーブル操作
#include <stdio.h>
char * getenv(const char * name)
戻り値:nameに関連付けられた値へのポインター、または見つからない場合はNULL

#include <std; ib.h>
int putenv(char * str);
int setenv(const char * name、const char * value、int rewrite); // 1ゼロ以外は、
int unsetenv(const char * name)を上書きすることを意味します;
戻り値:成功した場合は0を返し、エラーの場合はゼロ以外を返します

#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <string.h> extern char ** environ; 

void showenv(char ** env){int i = 0; char * str; while((str = env [i])!= NULL){ 
        printf( "%s \ n"、str); 
        i ++; 

    } 
} int main(int argc、char * argv []、char * envp []){ 
    printf( "envrison =%p、envp =%p \ n"、environ、envp); // 2変数量地址值一種・// showenv(environ); // printf( "------- \ n"); // showenv(envp); printf( "--------------- ------------- \ n "); char * oldpath = getenv(" PATH "); char * addpath =":/ tmp / hkui "; int newlen = strlen(oldpath)+1 + strlen(addpath)+1; 
    printf( "newlen =%d \ n"、newlen); char newpath [newlen]; 
    strcpy(newpath、oldpath); 
    strcat(newpath、addpath);


    printf( "newpath:%s \ n"、getenv( "PATH")); 
    putenv( "NAME = HKUI2018"); 
    printf( "NAME:%s \ n"、getenv( "NAME")); 


    0を返します。
}

 メモリ内のプロセスレイアウト

テキストセクション(コードセクション)
初期化データセクション(グローバルデータ、静的変数)
非初期化データ(グローバルデータ、静的変数)
ヒープ(手動で割り当てられたメモリスペースmalloc)
スタック(一方の端で閉じ、もう一方の端で開く)
mainパラメータ

プロセスがスタック領域に非ローカルジャンプを実装
するというヘッダーファイル<setjmp.h>の説明は、通常の関数呼び出しと戻りシーケンスを回避する方法を提供します。特に、マルチレベルのネストされた関数からの即時関数呼び出しを可能にします。 function。return

setjump、longjump
#include <setjmp.h>
int setjmp(jmp_buf env)
returns:直接呼び出しは0を返し、longjmp呼び出しから戻る場合は、ゼロ以外の値を返します(longjmp 2番目のパラメーターval)

void longjmp(jmp_buf env、int val)

setjmp()マクロは、longjmp()が状態情報を復元するときに後で使用できるように、現在の状態情報をenvに保存します。
setjmp()が直接呼び出された場合、戻り値は0です。longjmp()を呼び出したためにsetjmp()が呼び出された場合、戻り値は0ではありません
。setjmp()は、ifなどの特定の状況でのみ呼び出すことができます。ステートメント、switchステートメントとloopステートメントの条件付きテスト部分といくつかの単純な関係式では、
longjmp()を使用して、前回setjmp()が呼び出されたときにenvに保存された状態情報を復元します。
実行が終了すると、プログラムは、setjmp()が実行を終了したかのように
、setjmp()マクロ呼び出しを含む関数を実行続け、ゼロ以外の値valを返します。終了してはなりません。
アクセス可能なすべてのオブジェクトの値は、longjmp()が呼び出されたときと同じです。唯一の例外は、setjmp()を呼び出した後に、setjmp()マクロを呼び出す関数の非揮発性自動変数が変更された場合、Undefinedになることです。

非ローカルジャンプで注意が必要な問題
自動変数、レジスター、および揮発性変数レジスター内の変数の
元の値は、非ローカルジャンプの場合に復元できます
自動変数の潜在的な問題

#include <stdio.h> #include <stdlib.h> #include <setjmp.h> jmp_buf jmp; int g_v = 1; void fun(){ 
    printf( "jmp =%d \ n"、jmp); 
    longjmp(jmp、1); 
    printf( "jmp =%d \ n"、jmp); 
} int main(void){static int s_v = 1; 
    auto int a_v = 1; 
    レジスタr_v = 1; volatile v_v = 1; int * h_v =(int *)malloc(sizeof(int)); * h_v = 1; 
    printf( "1:g_v =%d、s_v =%d、a_v =%d、r_v =%d、v_v =%d、h_v =%d \ n"、g_v、s_v、a_v、r_v、v_v、* h_v ); 
    printf( "setjmp(jmp)=%d \ n"、setjmp(jmp)); if(setjmp(jmp)== 1){ 
        printf( "2:g_v =%d、s_v =%d、a_v =%d 、r_v =%d、v_v =%d、h_v =%d \ n "、g_v、s_v、a_v、r_v、v_v、* h_v); 
        exit(1); 
    } 

    g_v = 2; 
    s_v = 2; 
    a_v = 2; 
    r_v = 2;
    printf( "3:g_v =%d、s_v =%d、a_v =%d、r_v =%d、v_v =%d、h_v =%d \ n"、g_v、s_v、a_v、r_v、v_v、* h_v ); 
    fun(); return 0; 



}

[root @ centos1 process]#
。/ a.out 1:g_v = 1、s_v = 1、a_v = 1、r_v = 1、v_v = 1、h_v = 1
setjmp(jmp)= 0
3:g_v = 2、s_v = 2、a_v = 2、r_v = 2、v_v = 2、h_v = 2
jmp = 6294496
2:g_v = 2、s_v = 2、a_v = 1、r_v = 1、v_v = 2、h_v = 2

おすすめ

転載: blog.51cto.com/huangkui/2677781