亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁(yè) > 系統(tǒng) > Unix > 正文

UNIX高級(jí)環(huán)境編程(8)進(jìn)程環(huán)境(Process Environment)- 進(jìn)程的啟動(dòng)和退出、內(nèi)存布局、環(huán)境變量列表

2024-06-28 13:21:41
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友
UNIX高級(jí)環(huán)境編程(8)進(jìn)程環(huán)境(PRocess Environment)- 進(jìn)程的啟動(dòng)和退出、內(nèi)存布局、環(huán)境變量列表

在學(xué)習(xí)進(jìn)程控制相關(guān)知識(shí)之前,我們需要了解一個(gè)單進(jìn)程的運(yùn)行環(huán)境。

本章我們將了解一下的內(nèi)容:

  • 程序運(yùn)行時(shí),main函數(shù)是如何被調(diào)用的;
  • 命令行參數(shù)是如何被傳入到程序中的;
  • 一個(gè)典型的內(nèi)存布局是怎樣的;
  • 如何分配內(nèi)存;
  • 程序如何使用環(huán)境變量;
  • 程序終止的各種方式;
  • 跳轉(zhuǎn)(longjmp和setjmp)函數(shù)的工作方式,以及如何和棧交互;
  • 進(jìn)程的資源限制

?

1 main函數(shù)

main函數(shù)聲明:

int main (int argc, char *argv[]);

參數(shù)說(shuō)明:

  • argc:命令行參數(shù)個(gè)數(shù)
  • argv:指向參數(shù)列表數(shù)組的指針

main函數(shù)啟動(dòng)前:

  • C程序由內(nèi)核執(zhí)行,通過(guò)系統(tǒng)調(diào)用exec;
  • main函數(shù)調(diào)用前,執(zhí)行指定的啟動(dòng)路徑(start-up routine);
  • 可執(zhí)行文件認(rèn)為此地址為程序的啟動(dòng)地址,該地址由鏈接器指定;
  • 啟動(dòng)路徑從內(nèi)核獲取參數(shù)列表和環(huán)境變量,使得main函數(shù)可以在稍后被調(diào)用時(shí)可以獲取這些變量。

?

2 進(jìn)程終止

一共有8中終止進(jìn)程的方式,5種正常終止和3種異常終止。

5種正常終止:

  1. 從main函數(shù)返回;
  2. 調(diào)用exit;
  3. 調(diào)用_exit或_Exit;
  4. 最后一個(gè)線程返回;
  5. 最后一個(gè)線程調(diào)用pthread_exit。

3種異常終止:

  1. 調(diào)用abort;
  2. 接收到一個(gè)信號(hào);
  3. 最后一個(gè)線程應(yīng)答或者一個(gè)接收到一個(gè)退出請(qǐng)求

啟動(dòng)地址(start-up routine)同樣也是main函數(shù)的返回地址。

要獲取該地址,可以通過(guò)以下的方式:

exit (main(argc, argv));

?

退出函數(shù)

函數(shù)聲明:

#include <stdlib.h>

void exit(int status);

void _Exit(int status);

#include <unistd.h>

void _exit(int status);

函數(shù)細(xì)節(jié):

  • _exit和_Exit立刻返回到內(nèi)核;
  • exit函數(shù)返回內(nèi)核前會(huì)進(jìn)行一些清理環(huán)境工作;

返回一個(gè)整數(shù)和調(diào)用exit函數(shù),并傳入該整數(shù)的作用是相同的:

exit(0);

return 0;

?

atexit函數(shù)

函數(shù)聲明

#include <stdlib.h>

int atexit(void (*func)(void));

函數(shù)細(xì)節(jié)

  • 每個(gè)進(jìn)程可以注冊(cè)32個(gè)函數(shù),這些函數(shù)可以在主函數(shù)調(diào)用exit時(shí)自動(dòng)被調(diào)用
  • 通過(guò)atexit注冊(cè)的退出時(shí)處理函數(shù)稱(chēng)為退出句柄(exit handlers)
  • 這些退出句柄的調(diào)用順序?yàn)樽?cè)時(shí)的相反順序
  • exit函數(shù)第一次調(diào)用退出句柄時(shí),會(huì)關(guān)閉所有打開(kāi)的流
  • 如果主程序調(diào)用了exec系列函數(shù),則所有注冊(cè)的退出句柄都會(huì)被清空

?

程序啟動(dòng)和終止流程圖

?NewImage

Example:

#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");

}

?執(zhí)行結(jié)果:

NewImage

?

3 命令行參數(shù)Example:

#include "apue.h"

?

int

main(int argc, char *argv[])

{

? ? int ? ? i;

?

? ? for (i = 0; i < argc; i++)? ? ? /* echo all command-line args */

? ? ? ? printf("argv[%d]: %s/n", i, argv[i]);

? ? exit(0);

}

執(zhí)行結(jié)果:

NewImage?

?

4 環(huán)境變量列表

每個(gè)程序會(huì)接受一個(gè)環(huán)境變量列表,該列表是一個(gè)數(shù)組,由一個(gè)數(shù)組指針指向,該數(shù)組指針類(lèi)型為:

extern char **environ;

例如,如果環(huán)境變量里有5個(gè)字符串(C風(fēng)格字符串),如下圖所示:

NewImage

5 C程序的內(nèi)存布局

典型的C程序的內(nèi)存布局如下圖所示:

NewImage

上圖說(shuō)明:

  • 文本段(Text Segment),保存CPU將要執(zhí)行的機(jī)器指令。文本段是可共享的,所以某個(gè)程序多次執(zhí)行時(shí),對(duì)應(yīng)的文本段只需要在內(nèi)存中存有一份拷貝。文本段是只讀的(read-only),防止程序的指令被修改。
  • 已初始化數(shù)據(jù)段(initialized data segment),保存程序中被初始化的全局變量(定義在任何函數(shù)之外)。例如:int maxcount = 99; 全局變量變量maxcount被保存在初始化數(shù)據(jù)段。
  • 未初始化數(shù)據(jù)段(uninitialized data segment),也被稱(chēng)為BSS(block started by symbol),這個(gè)段中的數(shù)據(jù)在程序執(zhí)行之前被內(nèi)核初始化為0或者null。;例如定義一個(gè)全局變量(定義在任何函數(shù)之外),long sum[1000]; ?該變量保存在未初始化數(shù)據(jù)段中。
  • 棧(Stack):存儲(chǔ)臨時(shí)變量,函數(shù)相關(guān)信息。當(dāng)一個(gè)函數(shù)被調(diào)用時(shí),返回地址、調(diào)用者相關(guān)信息(如寄存器信息)會(huì)被保存在棧中。該被調(diào)用的函數(shù)會(huì)在棧上分配一部分空間保存它的臨時(shí)變量。函數(shù)的遞歸調(diào)用也是應(yīng)用這個(gè)原理。每一次函數(shù)調(diào)用自己,都會(huì)保存當(dāng)前函數(shù)的信息,然后再棧上開(kāi)辟一個(gè)新的空間用于保存該次函數(shù)的信息,和以前的函數(shù)并沒(méi)有影響。
  • 堆(Heap):動(dòng)態(tài)內(nèi)存分配位置。堆的位置位于未初始化數(shù)據(jù)段和棧的中間。

?

6 內(nèi)存分配(Memory Allocation)

有三個(gè)函數(shù)可以用于內(nèi)存分配:

  • malloc:分配指定字節(jié)數(shù)的內(nèi)存,未初始化。
  • calloc:分配指定數(shù)目的對(duì)象大小的內(nèi)存,內(nèi)存初始化為0;
  • realloc:增加或減小之前分配的內(nèi)存。移動(dòng)舊內(nèi)存的內(nèi)容到新的更大的內(nèi)存塊,多余的部分內(nèi)存未初始化。

函數(shù)聲明:

#include <stdlib.h>

void *malloc(size_t size);

void *calloc(size_t nobj, size_t size);

void *realloc(void *ptr, size_t newsize);

void free(void* ptr);

函數(shù)細(xì)節(jié):

  1. 三個(gè)函數(shù)返回的內(nèi)存指針一定是內(nèi)存對(duì)齊的,這樣可以用來(lái)保存于不同的對(duì)象;
  2. free函數(shù)用于釋放ptr指向的內(nèi)存,被分配的內(nèi)存放入內(nèi)存池中用于下次的內(nèi)存分配;
  3. realloc函數(shù)用于改變之前分配的內(nèi)存的大小。比如運(yùn)行時(shí)我們申請(qǐng)了一段內(nèi)存用于存儲(chǔ)512個(gè)元素的數(shù)組,后來(lái)發(fā)現(xiàn)內(nèi)存大小不夠,這時(shí)可以調(diào)用realloc。如果操作系統(tǒng)發(fā)現(xiàn)在當(dāng)前內(nèi)存的后面有足夠的內(nèi)存,則直接分配多余的內(nèi)存到當(dāng)前內(nèi)存中,然后返回傳入的指針(即直接擴(kuò)展內(nèi)存)。但是如果當(dāng)前內(nèi)存后面沒(méi)有足夠大小的空間,則系統(tǒng)重新分配一個(gè)足夠大的內(nèi)存,將舊內(nèi)存塊中得內(nèi)容拷貝到新內(nèi)存塊中,然后返回新內(nèi)存的地址。
  4. 內(nèi)存分配函數(shù)使用系統(tǒng)調(diào)用sbrk來(lái)實(shí)現(xiàn)。該系統(tǒng)調(diào)用的作用是擴(kuò)展進(jìn)程的堆。
  5. 一般實(shí)際分配的內(nèi)存塊都比請(qǐng)求的要大,多出來(lái)的部分用來(lái)存儲(chǔ)內(nèi)存塊大小、指向下一內(nèi)存塊的指針等信息。寫(xiě)覆蓋信息記錄區(qū)的錯(cuò)誤是非常隱蔽而且嚴(yán)重的。

?

7 環(huán)境變量(Environment Variable)

環(huán)境變量的字符串形式:

name=value

?內(nèi)核不關(guān)注環(huán)境變量,各種應(yīng)用才會(huì)使用環(huán)境變量。

獲取環(huán)境變量值使用函數(shù)getenv。

#include <stdlib.h>

char* getenv(const char* name);

// Returns: pointer to value associated with name, NULL if not found

修改環(huán)境變量的函數(shù):

#include <stdlib.h>

int putenv(char* str);

int setenv(const char* name, const char* value, int rewrite);

int unsetenv(const char* name);

?函數(shù)細(xì)節(jié):

  • 函數(shù)putenv傳入一個(gè)字符串,形式為name=value,加入到環(huán)境變量列表中。如果name已經(jīng)存在,先刪除舊的定義。
  • 函數(shù)setenv傳入一個(gè)name和一個(gè)value,如果name已經(jīng)存在,則參數(shù)rewrite決定是否覆蓋舊的定義,如果rewrite為非零,則會(huì)覆蓋舊的定義。
  • 函數(shù)unsetenv刪除name的定義,如果name不存在,也不報(bào)錯(cuò)。?

?修改環(huán)境變量列表的過(guò)程是一件很有趣的事情

從上面的C程序內(nèi)存布局圖中可以看到,環(huán)境變量列表(保存指向環(huán)境變量字符串的一組指針)保存在棧的上方內(nèi)存中。

在該內(nèi)存中,刪除一個(gè)字符串很簡(jiǎn)單。我們只需要找到該指針,刪除該指針和該指針指向的字符串。

但是增加或修改一個(gè)環(huán)境變量困難得多。因?yàn)榄h(huán)境變量列表所在的內(nèi)存往往在進(jìn)程的內(nèi)存空間頂部,下面是棧。所以該內(nèi)存空間無(wú)法被向上或者向下擴(kuò)展。

所以修改環(huán)境變量列表的過(guò)程如下所述:

  • 如果我們修改一個(gè)已經(jīng)存在的name:
    • 如果新的value的大小比已經(jīng)存在的value小或者相當(dāng),直接覆蓋舊的value;
    • 如果新的value的大小比已經(jīng)存在的value大,則我們必須為新的value malloc一個(gè)新的內(nèi)存空間,拷貝新value到該內(nèi)存中,替換指向舊value的指針為指向新value的指針。
  • 如果我們新增一個(gè)環(huán)境變量:
    • 首先我們需要調(diào)用malloc為字符串name=value分配空間,拷貝該字符串到目標(biāo)內(nèi)存中;
    • 如果這是我們第一次添加環(huán)境變量,我們需要調(diào)用malloc分配一個(gè)新的空間,拷貝老的環(huán)境量列表到新的內(nèi)存中,并在列表后新增目標(biāo)環(huán)境變量。然后我們?cè)O(shè)置environ指向新的環(huán)境變量列表。
    • 如果這不是我們第一次新增環(huán)境變量,則我們只需要realloc多分配一個(gè)環(huán)境變量的空間,新增的環(huán)境變量保存在列表尾部,列表最后仍然是一個(gè)null指針。

?

小結(jié)

本篇介紹了進(jìn)程的啟動(dòng)和退出、內(nèi)存布局、環(huán)境變量列表和環(huán)境變量的修改。

下一篇將接著學(xué)習(xí)四個(gè)函數(shù)setjmp、longjmp、getrlimit和setrlimit。

?

?

參考資料:

《Advanced Programming in the UNIX Envinronment 3rd》


發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
欧美偷拍综合| xvideos成人免费中文版| 久久久久久久久久久9不雅视频| 中文字幕免费在线播放| 99精品视频免费版的特色功能| 国产一区二区三区免费观看在线| 日本中文字幕中出在线| 麻豆免费视频网站入口| 一区二区三区在线视频111| 天天超碰亚洲| 一本到av在线| 日韩成人在线电影| 精品国产一区二区三区久久久久久| 亚洲黄色网址大全| 99精品国产高清在线观看| 国产精品国产三级国产aⅴ中文| 国产娇喘精品一区二区三区图片| 91久久国产综合久久蜜月精品| 91精品婷婷国产综合久久竹菊| 亚洲高清毛片| 97精品人妻一区二区三区| 影音先锋中文在线视频| 天堂视频在线免费观看| 日韩成人在线视频观看| 国产一卡2卡3卡4卡网站免费| 成年人在线观看av| 91久久久久国产一区二区| 九九九伊在线综合永久| 巨大荫蒂视频欧美另类大| 99久久精品国产成人一区二区| 好吊妞这里只有精品| 午夜久久久久久久久久| 影音先锋另类| 免费看黄色网| 网址你懂得在线观看| 日本午夜精品视频在线观看| 日韩日韩日韩日韩日韩| 在线一区二区观看| 茄子视频成人在线观看| 5566av亚洲| 国产成人综合精品| 黄色毛片免费看| 91日韩中文字幕| 欧美猛男男办公室激情| 韩国三级在线播放| 99精品偷自拍| 狠狠色综合日日| 在线亚洲精品自拍| 奇米影视第四色7777| 一本久道久久久| 一级黄色录像在线观看| 国产在线精品一区二区不卡了| 一区二区三区亚洲| 日本一区二区精品视频| 国产日韩综合一区二区性色av| av在线不卡免费观看| 2024亚洲男人天堂| 蜜臀av在线播放一区二区三区| 91蝌蚪国产九色| av日韩在线网站| 亚洲ⅴ国产v天堂a无码二区| 亚洲天堂网在线播放| 日本怡春院一区二区| 精品调教chinesegay| 色一色在线观看视频网站| 粉嫩av在线播放| 久久99精品久久久久子伦| 中文亚洲免费| 精品一区二区三区免费观看| 日韩欧乱色一区二区三区在线| 亚洲精品国产精品国自产网站| 久久不卡免费视频| 成 人 黄 色 小说网站 s色| **精品中文字幕一区二区三区| youjizz.com国产| 五月激情综合婷婷| 久久精品国产精品亚洲色婷婷| 毛片中文在线观看| 奇米综合一区二区三区精品视频| 高端美女服务在线视频播放| 欧洲av无码放荡人妇网站| www.性欧美| 久久99国产精品二区高清软件| 国产免费无码一区二区视频| 成人在线视频免费播放| 热久久精品免费视频| 91精东传媒理伦片在线观看| 国产一级一片免费播放| 国产一区视频在线看| 国产成人啪午夜精品网站男同| 国偷自产av一区二区三区麻豆| 亚洲成人午夜在线| 欧美极品美女视频| 北条麻妃69av| 欧美久久综合网| 欧美日韩国产成人高清视频| 凹凸国产熟女精品视频| 久久久久久久久久av| 欧美xxxx免费虐| 视频在线在亚洲| 亚洲第一伊人| 国产特级淫片高清视频| 在线国产精品播放| 一级毛片免费在线| 成人在线分类| 538国产精品一区二区免费视频| 国产99在线免费| 国产对白叫床清晰在线播放| 国产精品久久久久影视| 一级日本不卡的影视| 欧美精品卡一卡二| 日本成人一区二区| 久久一区二区三区超碰国产精品| 欧美特黄级在线| zzjj国产精品一区二区| 久久国产精品系列| 男女男精品视频网站| 国产黄色免费看| 国产精品嫩草影院精东| 91视频最新入口| 国产精品试看| 国产一区二区四区| 生活片a∨在线观看| 欧美特大特白屁股xxxx| 一区二区91美女张开腿让人桶| 青草视频在线观看视频| 西西午夜视频| 日本一级淫片免费放| 欧美一区二区三区电影在线观看| 欧美人狂配大交3d怪物一区| 国内一区二区三区精品视频| 欧美精品123区| 国内久久久精品| 亚洲综合一区二区三区| 青青草原av在线播放| 美女在线一区| 久久伊人成人网| 国产激情一区二区三区| 精品亚洲aⅴ无码一区二区三区| 欧美视频中文在线看| 国产精品一区二区三区久久久| 不卡中文字幕| 国产av天堂无码一区二区三区| 婷婷精品国产一区二区三区日韩| 97在线观看免费高| 亚洲一区二区视频在线| 中文字幕在线观看高清| 性欧美高清强烈性视频| 男人与禽猛交狂配| 99在线影院| 日韩精品1区2区| 国产伦精品一区二区三区妓女下载| 二区在线观看| 国产精品乱码久久久久| 在线观看免费av网| 中文字幕在线日本| 中文字幕日韩精品无码内射| 欧美国产精品一区| 日韩av中文字幕一区| 亚洲风情亚aⅴ在线发布| 久久一区二区三区欧美亚洲| 91精品国产综合久久香蕉麻豆| 免费a级片网站| 黄色av资源| 国产伦精品一区二区三区照片91| 欧美一区二区三区高清视频| 成人免费视频网站在线看| 九九热最新地址| 精品久久久av| 国产极品在线视频| а天堂中文最新一区二区三区| 欧美成人激情| 午夜精品久久久久久久99| 严阵以待中文社区| 国产三级黄色片| 麻豆影视在线播放| 久久国产精品久久久| 亚洲一区二区三区精品视频| 啊啊啊一区二区| 精品视频免费在线| 成人免费电影网址| 亚洲精品久久嫩草网站秘色| 日本不卡一区二区在线观看| 中日韩免费视频中文字幕| 欧美性色黄在线视频| 黄色污网站在线观看| 国产同性人妖ts口直男| 亚洲精品成人精品456| 99久久精品免费| 亚洲综合一二三| 欧美一级一区二区三区| 国产综合色在线| 国产69精品久久99不卡| 国产精品99久久久久久人| 久久国产视频一区| 欧美黑人xxxxx性受| 蝌蚪视频在线播放| 秋霞成人午夜鲁丝一区二区三区| 国产精品入口麻豆九色| 色综合一区二区日本韩国亚洲| 亚洲精品在线网站| 丰满少妇又爽又紧又丰满69| 国产调教一区二区三区| 亚洲男人天堂久| 久久成人国产| 97精品视频在线观看| 中文字幕第22页| 欧美中在线观看| 午夜视频福利在线观看| 成人免费视频观看视频| 国产成人综合美国十次| 丁香激情综合国产| 影音先锋亚洲电影| 日韩国产专区| 国产人成在线观看| 高潮毛片7777777毛片| 97中文字幕在线观看| jizzjizzjizz中国免费| 97国产精品视频人人做人人爱| 中文字幕亚洲精品在线| 欧美午夜美女看片| 欧美一区二区三区久久精品茉莉花| 国产在线视频你懂的| 中文字幕a级片| 在线精品国产亚洲| 久久精品久久久久电影| 99视频免费在线观看| av成人app永久免费| 亚洲国产黄色片| 在线看一级片| 另类国产精品一区二区| 黄色在线视频观看网站| 天天摸天天干天天操| 2019年中文字幕| 日韩精品免费一区| aaa大片免费观看| 欧美精品三级在线观看| 丰满少妇一区二区三区| 欧美一级淫片a免费视频| 99高清免费国产自产拍| 高清视频在线观看三级| 午夜色香蕉导航| 国产裸体写真av一区二区| 亚洲综合一二区| 国产野外战在线播放| 谁有免费的黄色网址| 国产精品久久久久久户外露出| eeuss影院网站免费观看| 中文字幕在线观看精品| 你懂的在线播放| 久草在线综合| 一区二区三区加勒比av| av基地在线| 女同性恋一区二区| 无码人妻一区二区三区线| 99久久婷婷国产精品综合| 日韩三级精品| 在线免费看av网站| 色先锋av资源| 日本电影欧美片| 中文字幕日韩一区二区三区不卡| 波多野结衣中文字幕在线播放| 国产视频亚洲| 蜜桃91麻豆精品一二三区| 岛国片av在线| 蜜桃一区二区| 成人免费看黄yyy456| 中文字幕欧美国产| 日日夜夜天天操| 高清av免费看| 99re在线视频这里只有精品| 婷婷视频一区二区三区| 日韩va欧美va亚洲va久久| 天天色棕合合合合合合合| 亚洲黄色毛片| 欧美国产小视频| 色婷婷777777仙踪林| 男人女人拔萝卜视频| 高清成人在线| 欧美777四色影视在线| gogo久久日韩裸体艺术| 日韩欧美视频一区二区三区四区| 欧洲s码亚洲m码精品一区| 日韩毛片免费视频一级特黄| 你懂的在线免费观看| 色999日韩国产欧美一区二区| 国产成人免费视| 黄色三级在线观看| 成人香蕉社区| 国产欧美1区2区3区| 亚洲精品在线观看www| 秋霞av鲁丝片一区二区| 久久久久久久久久久久久久久久久| 亚洲精品小说| 国产精品无码99re| 高h调教冰块play男男双性文| 亚洲免费av在线| 亚洲中文字幕无码av永久| 成人精品福利视频| 精品无码一区二区三区| 日韩在线视频中文字幕| 1769视频在线播放免费观看| 国产精品久久久久影院| 特一级黄色录像| 一代武则天秘史| 成人毛片在线精品国产| 亚洲国产精品久久久久秋霞蜜臀| 你懂的亚洲视频| 另类中文字幕国产精品| 久久国产色av| 国产一区不卡视频| 亚洲天堂免费看| 久久精品在这里| 亚洲综合在线不卡| 久久久久久国产精品三级玉女聊斋| 久久久久久久片| 国产精品久久一| 亚洲色图综合网| 成人的网站免费观看| 欧美va天堂在线| 91视频在线视频| 久久精品成人一区二区三区蜜臀| 久久久99免费| 粉嫩精品一区二区三区在线观看| 91在线视频播放| 2023国产精华国产精品| 一道精品一区二区三区| 青青操在线观看|