在學習進程控制相關知識之前,我們需要了解一個單進程的運行環境。
本章我們將了解一下的內容:
?
1 main函數main函數聲明:
int main (int argc, char *argv[]);
參數說明:
main函數啟動前:
?
2 進程終止一共有8中終止進程的方式,5種正常終止和3種異常終止。
5種正常終止:
3種異常終止:
啟動地址(start-up routine)同樣也是main函數的返回地址。
要獲取該地址,可以通過以下的方式:
exit (main(argc, argv));
?
退出函數函數聲明:
#include <stdlib.h>
void exit(int status);
void _Exit(int status);
#include <unistd.h>
void _exit(int status);
函數細節:
返回一個整數和調用exit函數,并傳入該整數的作用是相同的:
exit(0);
return 0;
?
atexit函數函數聲明
#include <stdlib.h>
int atexit(void (*func)(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");
}
?執行結果:
?
3 命令行參數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);
}
執行結果:
?
?
4 環境變量列表每個程序會接受一個環境變量列表,該列表是一個數組,由一個數組指針指向,該數組指針類型為:
extern char **environ;
例如,如果環境變量里有5個字符串(C風格字符串),如下圖所示:
典型的C程序的內存布局如下圖所示:
上圖說明:
?
6 內存分配(Memory Allocation)有三個函數可以用于內存分配:
函數聲明:
#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);
函數細節:
?
7 環境變量(Environment Variable)環境變量的字符串形式:
name=value
?內核不關注環境變量,各種應用才會使用環境變量。
獲取環境變量值使用函數getenv。
#include <stdlib.h>
char* getenv(const char* name);
// Returns: pointer to value associated with name, NULL if not found
修改環境變量的函數:
#include <stdlib.h>
int putenv(char* str);
int setenv(const char* name, const char* value, int rewrite);
int unsetenv(const char* name);
?函數細節:
?修改環境變量列表的過程是一件很有趣的事情
從上面的C程序內存布局圖中可以看到,環境變量列表(保存指向環境變量字符串的一組指針)保存在棧的上方內存中。
在該內存中,刪除一個字符串很簡單。我們只需要找到該指針,刪除該指針和該指針指向的字符串。
但是增加或修改一個環境變量困難得多。因為環境變量列表所在的內存往往在進程的內存空間頂部,下面是棧。所以該內存空間無法被向上或者向下擴展。
所以修改環境變量列表的過程如下所述:
?
小結本篇介紹了進程的啟動和退出、內存布局、環境變量列表和環境變量的修改。
下一篇將接著學習四個函數setjmp、longjmp、getrlimit和setrlimit。
?
?
參考資料:
《Advanced Programming in the UNIX Envinronment 3rd》
新聞熱點
疑難解答