第七章-進程環境

main函數

  • C程序總是從main函數開始執行。其原型是:
int  main(int argc, char *argc[]);
/*argc是命令行參數的數目,argv是指向參數的各個指針所構成的數組*/
  • 內核使程序執行的唯一方法是調用一個exec函數

進程終止

  • 進程終止8種方式:
  1. 從main返回
  2. exit(自願)
  3. _exit或_Exit(自願)
  4. 最後一個線程從其啓動例程返回
  5. 從最後一個線程調用pthread_exit
  6. 調用abort
  7. 接收一個信號
  8. 最後一個線程對取消請求做出響應
    請看如下經典的”hello world"程序
#include        <stdio.h>
main()
{
	printf("hello, world!\n");
}

以下是對該程序執行終止後的退出狀態碼的檢查

xiangke@xiangke-virtual-machine:/home/apue.3e/environ$ ./hello1 
hello, world!
xiangke@xiangke-virtual-machine:/home/apue.3e/environ$ echo $?
14
xiangke@xiangke-virtual-machine:/home/apue.3e/environ$ gcc -std=c99 hello1.c 
hello1.c:3:1: warning: return type defaults to ‘int’ [-Wimplicit-int]
 main()
 ^
xiangke@xiangke-virtual-machine:/home/apue.3e/environ$ ./a.out 
hello, world!
xiangke@xiangke-virtual-machine:/home/apue.3e/environ$ echo $?
0
xiangke@xiangke-virtual-machine:/home/apue.3e/environ$ 
  • 其終止碼是一個隨機的數 14
  • 用1999 ISO C編譯器擴展,其終止碼總是爲0
#include <unistd.h>
       void _exit(int status);
       #include <stdlib.h>
       void exit(int status);//輸出緩衝區中的所有數據都會被沖洗
       void _Exit(int status);
       //這些函數都沒有返回值,status就是進程終止狀態
  • 一個進程可登記多至32個函數,在進程終止的時候,這些函數被調用,稱爲終止處理程序
#include <stdlib.h>
       int atexit(void (*function)(void)); 
  • 進程終止處理程序被調用的順序與他們被登記的順序剛好相反,請看如下實例
#include "apue.h"
static void     my_exit1(void);
static void     my_exit2(void);
int
main(void)
{
        if (atexit(my_exit2) != 0)
                err_sys("can't register my_exit2");
        if (atexit(my_exit1) != 0)
                err_sys("can't register my_exit1");
        if (atexit(my_exit1) != 0)
                err_sys("can't register my_exit1");

        printf("main is done\n");
        return(0);
}
static void
my_exit1(void)
{
        printf("first exit handler\n");
}
static void
my_exit2(void)
{
        printf("second exit handler\n");
}

執行結果如下

xiangke@xiangke-virtual-machine:/home/apue.3e/environ$ ./doatexit 
main is done
first exit handler
first exit handler
second exit handler
xiangke@xiangke-virtual-machine:/home/apue.3e/environ$ 

命令行參數

下面看一個顯示命令行參數的實例,如下:

#include "apue.h"
int
main(int argc, char *argv[])
{
        int             i;
        /*for (i = 0; argv[i] != NULL; i++)*/
        for (i = 0; i < argc; i++)              /* echo all command-line args */
                printf("argv[%d]: %s\n", i, argv[i]);
        exit(0);
}

該實例運行結果如下
在這裏插入圖片描述

環境表

  • 每個程序都接收到一張環境表,全局參數environ指向一個指針數組,該參數稱爲環境指針
    extern char **environ
    如下,是5個字符串組成的環境
    在這裏插入圖片描述
    每個字符串爲一個環境參數,其格式是name=value

C程序的存儲空間佈局

  • 正文段,是CPU執行的機器指令部分。它是可共享的
  • 初始化數據段,包含程序中明確賦值的變量
  • 未初始化數據段,即bss(block started by symbol)
  • 棧,自動變量和每次函數調用時所需保存的信息
  • 堆。動態存儲分配
    如下是一種存儲空間的典型分配方式
    在這裏插入圖片描述
  • 存放在磁盤程序文件中的段只有正文段和初始化數據段
  • size命令可以報告正文段、數據段和bss段的長度,例如
    在這裏插入圖片描述

共享庫

  • 共享庫是公用函數的集合
  • 它減少了可執行文件的長度
  • 庫函數的版本升級不影響用該庫函數的程序
  • 但是會增加程序運行時間開銷

存儲空間分配

以下說明3個用於存儲空間動態分配函數

 #include <stdlib.h>
       void *malloc(size_t size);
       void free(void *ptr);
       void *calloc(size_t nmemb, size_t size);
       void *realloc(void *ptr, size_t size);
  • 這三個函數返回的指針一定是適當對齊的,使其可用於任何數據對象
  • realloc函數可以增、減以前分配的存儲區的長度
  • 如果忘記用free 釋放存儲空間,會使進程佔用的存儲空間連續增加,這被稱爲內存泄漏

環境變量

#include <stdlib.h>
//取得環境變量的值
       char *getenv(const char *name);
       int putenv(char *string);//添加或改變環境變量的值
       int setenv(const char *name, const char *value, int overwrite);//添加環境變量,overwrite!=0,則覆蓋已存在的環境變量的值,否則不改變
       int unsetenv(const char *name)//刪除環境變量
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章