進程終止,環境表以及在內存中佈局和非局部跳轉

進程ID:
每一個linux進程都必定有一個惟一的數字標識符,稱爲進程ID(老是一個非負整數)php

進程終止:
正常終止:
1.從Main返回(return)
2.調用exit (標準庫)
3.調用_exit或_Exit (內核提供)
4.最後一個線程從啓動例程返回
5.最後一個線程調用pthread_exit
異常終止:
調用abort(信號相關)
接收到一個信號並終止(信號相關)
最後一個線程對取消請求作相應
exit與_exit() 區別 是否刷新緩存區
flush I/O
atexit 函數linux

exit:先刷新緩存區,而後結束進程 ,在結束以前調用信號註冊函數atexit
_exit:不刷新緩存區 直接從進程退出,由內核直接結束進程 沒通過atexitcentos

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);
    }

    FILE *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("process error\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 exit]# more *.txt
::::::::::::::
_exit.txt
::::::::::::::
::::::::::::::
exit.txt
::::::::::::::
hellophp
::::::::::::::
return.txt
::::::::::::::
hellophp

進程的環境表佈局

獲取當前進程的環境表
1.經過別的地方定義的 引入過來
extern char **environ
2.經過main的第三個參數測試

進程中環境表操做
#include <stdio.h>
char *getenv(const char *name)
返回:指向與name關聯的value指針,若未找到則返回NULLui

#include <std;ib.h>
int putenv(char *str);
int setenv(const char *name,const char *value,int rewrite); //1非0表示覆蓋
int unsetenv(const char *name);
返回:成功返回0,出錯返回非0spa

#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("oldpath:%s\n",oldpath);
    setenv("PATH",newpath,1);
    printf("newpath:%s\n",getenv("PATH"));
    putenv("NAME=HKUI2018");
    printf("NAME:%s\n",getenv("NAME"));


    return 0;
}

 進程在內存中佈局線程

正文段(代碼段)
初始化數據段(全局數據,靜態變量)
非初始化數據(全局數據,靜態變量)
堆(手動分配的內存空間 malloc)
棧(一端封閉,一端開口)
main參數

進程在棧區實現非局部跳轉
頭文件<setjmp.h>中的說明提供了一種避免一般的函數調用和返回順序的途徑,特別的,它容許當即從一個多層嵌套的函數調用中返回

setjump,longjump
#include <setjmp.h>
int setjmp(jmp_buf env)
返回:直接調用返回0,若從longjmp調用返回,則返回非0值(longjmp第二個參數 val)

void longjmp(jmp_buf env,int val)

setjmp()宏把當前狀態信息保存到env中,供之後longjmp()恢復狀態信息時使用。
若是是直接調用setjmp(),那麼返回值爲0;若是是因爲調用longjmp()而調用setjmp(),那麼返回值非0
setjmp()只能在某些特定狀況下調用,如在if語句、 switch語句及循環語句的條件測試部分以及一些簡單的關係表達式中
longjmp()用於恢復由最近一次調用setjmp()時保存到env的狀態信息。
當它執行完時,程序就象setjmp()剛剛執行完並返回非0值val那樣繼續執行
包含setjmp()宏調用的函數必定不能已經終止。
全部可訪問的對象的值都與調用longjmp()時相同,惟一的例外是,那些調用setjmp()宏的函數中的非volatile自動變量若是在調用setjmp()後有了改變,那麼就變成未定義的

非局部跳轉應注意的問題
自動,寄存器和易失變量
寄存器中的變量再非局部跳轉時可恢復原始值
自動變量的潛在問題

#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;
    register 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;
    v_v=2;
    *h_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

相關文章
相關標籤/搜索