Linux_進程學習筆記_持續更新

進程的終止函數

C程序的啓動函數是main,也是進程代碼的入口點;
main(int argc, char *argv[]);
argc:參數個數
argv[]:傳入的參數表

當內核啓動C程序時,會調用main函數前調用特殊的啓動函數來獲取main函數的地址和傳遞main函數的參數,並且將這些信息填寫到進程控制塊中。

正常終止:
(1)從main函數中返回
(2)在任意代碼中調用
在這裏插入圖片描述

終止程序的2個exit函數:
(1)頭文件stlib.h,函數定義:void exit(int status)
(2)頭文件unistd.h,函數定義:void _exit(int status)
相同點:
調用這兩個函數都會正常地終止一個進程
不同點:
_exit函數:調用_exit函數將會立即返回內核
exit函數:調用exit函數,會執行下面3個操作:
1)執行預先註冊地終止處理函數
2)執行文件I/0操作地善後工作,使得所有緩衝地輸出數據被更新到相應地設備
3)返回內核

return 與 exit地區別:
(1)reuan 是C語言地關鍵字,exit是POSIX API函數
(2)在main函數中,執行return和調用exit函數會產生相同地效果
(3)在子函數中,執行return僅僅從子函數中返回,而調用exit函數將會退出當前進程。

執行exit函數後地一些效應:
(1)當進程終止時,程序可能需要進行一些自身地清理工作,如日誌登記、資源釋放等;
(2)通過atexit函數或on_exit函數允許進程註冊若干終止處理函數,當進程終止時,這些終止處理函數將會被自動調用。

註冊終止處理函數:
(1)頭文件stdlib.h

  1. int atexit(void(*func)(void));
  2. int on_exit(void(func)(int, void), void *arg)

(2)ABSI C規定一個進程最多隻能註冊32個終止處理函數
(3)當顯示調用或隱含調用exit函數終止進程(從main中返回、最後一個線程退出等)將會回調這些註冊終止處理函數(最先註冊地函數最後被回調)
(4)顯示調用_exit函數終止進程時將不會回調這些註冊地終止函數

atexit例子:

void func1() {
	printf("func1 is called\n");
}
void func2() {
	printf("func2 is called\n");
}
void fun3() {
	printf("func3 is called\n");
}

int main(int argc, char **argv) {
	atexit(func1);
	atexit(func2);
	atexit(func3);
	printf("process exit\n");
	return 0;
}

程序運行效果:(感覺有點像棧)
在這裏插入圖片描述

on_exit列子:

void func1(int status, void *arg) {
	printf("func1 exit status is %d\n", status);
	printf("func1 arg is %d\n", *((int *)arg));
}
void func2(int status, void *arg) {
	printf("func2 exit status is %d\n", status);
	printf("func2 arg is %d\n", *((int *)arg));
}
void func3(int status, void *arg) {
	printf("func3 exit status is %d\n", status);
	printf("func3 arg is %d\n", *((int *)arg));
}

int i, j, k;
int main(int argc, char **argv) {
	i = 3; 
	on_exit(func1, (void *)&i);
	j = 4;
	on_exit(func2, (void *)&j);
	k = 5;
	on_exit(func3, (void *)&k);
	printf("process exit\n");
	return 0;
} 

運行效果:
在這裏插入圖片描述

進程的環境

進程內存空間佈局
這裏有兩個,一個是進程的內核空間資源,一個是用戶空間資源;’
在這裏插入圖片描述

用戶空間:
正文:CPU執行的代碼部分,正文段通常是共享、可讀的。
數據段:

  1. 初始化的數據段:保研程序中需明確賦初值的變量,如全局變量int maxcount=99;
  2. 未初始化的數據段:程序執行之前,將此段中的數據初始化未0,如全局變量long sum[1000];

棧:主要用於支撐函數調用存放參數、局部變量等等

命令行參數:

  1. ls[參數]<路徑或文件名>
  2. mkdir
  3. copy

例子:

#include <stdio.h>
int main(int argc, char ** argv) {
	int i;
	for(i = 0; i < argc; i ++)
		printf("Argument %d is %s.\n", i, argv[i]);
		return 0;
}

運行效果:
在這裏插入圖片描述

環境變量表:
環境變量是Linux系統所特有的;

  1. 每個進程都會自己的環境變量表

  2. 通過全局的環境執指針(environ)可以直接訪問環境變量表(字符傳數組)
    1)頭文件:unistd.h
    2)extern char **environ;

  3. 環境變量字符串形式爲"name = value",name是環境變量名稱,value爲環境變量賦值
    在這裏插入圖片描述

  4. 獲取環境變量的方法
    1)直接通過environ變量訪問環境表
    2)使用getenv函數

  5. getenv函數用於獲取環境變量值
    1)頭文件:stdlib.h
    2)char* getenv(const char *name)
    3)指定環境變量的名稱,返回環境變量字符串指針,若未找到則返回空之指針

  6. 設置環境變量的三種方法
    1)putenv
    2)setenv
    3)unsetenv

  7. putenv函數將環境變量字符串放入環境變量表中;若該字符串已經存在,則覆蓋
    1)頭文件:stdlib.h
    2)int putenv(char *str);

  8. setenv
    1)頭文件:stdlib.h
    2)int setenv(const char* name, const char* value, int rewrite);
    3)setenv將指定環境變量的值設置爲參數指定值(更改環境變量字符串)
    4)若是name已經存在, rewrite不等於0,則刪除其原先的定義;rewrite等於0,則不刪除其原先的定義

  9. unsetenv
    1)頭文件:stdlib.h
    2)int unsetenv(const char* name)

    1. 刪除指定的環境變量字符串
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章