歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux編程 >> Linux編程 >> Linux編程---進程基礎

Linux編程---進程基礎

日期:2017/3/1 9:42:58   编辑:Linux編程

進程這個概念大家都很熟悉了吧...我就不多說了..


首先是進程環境.也就是Shell相關的內容.

這都是很基礎的我就挑一些我自己都不太清楚的寫寫.

一.命令行參數

POSIX對命令行的語法約定:

1.實用程序名至少兩個,至多9個字符,且只包含小寫字母和數字.(Linux應該不止9個吧.我覺得這是Unix下shell的規定).

2.選項名必須是但個字母或者數字,-W選項保留給實現擴展使用,不允許多數字選項.

3.選項和它的選項值可以作為也可以不作為分開的單詞.即-ofoo和-o foo是一樣的..(我看的達內視頻,裡面有個老師就喜歡這麼寫..)

4.如果多個選項均不要求有選項值的話,可以集中在一個短橫線分隔符之後作為一個單詞,因此’-abc’和’-a -b -c’等價.(貌似鳥哥書上寫過...但是我完全忘了...)

5.第一次出現的參數’--’終止所有選項.後繼的任何參數均視為操作數.即使他們是以’-’開頭的單個字符也是如此.貌似安裝程序的時候遇到這個情況比較多...但我記得我一搞寫好多個’--’接在後面.

6.多個選項可按任意順序出現,單個選項也可多次出現,其解釋留給應用程序.

7.僅由一個短橫線字符組成的單詞按操作數解釋.UNIX系統約定,它用於指定來自標准輸入流的輸入或標准輸出流的輸出.例如,如下命令中,單個短橫線’-’是選項參數-o的值,他代表標准輸出流,即指定將會變文件輸出到標准輸出流.

gcc -S file.c -o - -pipe

這個意思我猜是直接把輸出輸出到NULL文件中...-pipe表示用管道代替過程中的臨時文件.我也是第一次曉得這個-pipe參數.這麼寫了之後比較簡單的makefile貌似都可以不寫clean了?

是否每個shell程序都要寫一個函數來分析這些命令行參數呢?

實際上已經有了庫函數幫忙做這件事情了...(原來寫過幾個小程序都是自己寫函數分析的....)

int getopt(int argc,char 8const argv[],const char *optstring);

前兩個參數就是main後面的參數.第三個參數就是解析出來串的結果.每次調用一個getopt則獲得一個optstring參數.

這個optstring參數可能比較復雜.注意,這裡不是提取出參數放到optstring中,而是根據optstring來提取出參數是怎樣的..還是舉個例子吧.

c=getopt(argc,argv,”:f:is”)

“:f:is”中的順序不重要.開頭的”:”表示在後面遇到錯誤之後不返回’?’,而是返回’:’.

”f:”表示f這個參數後面要跟一個操作數.

第一次調用optstring的時候會對optstring分析.然後每次遇到f,i,s這三個之一的參數時,就會返回其當得到參數類型(f,i,s之一).返回f的時候,同時會設置optarg.這個optarg是一個全局字符指針.也就是相當於把’:’在命令行中所表示的操作數給optarg.當遇到未知參數的時候,optarg被設置為’?’.同時c也被設置為’?’.

這個函數配置了四個全局變量

optarg----就是解析出來的內容

optind----再次調用getopt的時候要分析argv.這是個下標值.

optopt----最後一個未知選項.

opterr----用來報錯.如果在getopt調用之前就設置不為0,並且opstring的開頭不是”:”,getopt在遇到位置選項字符或缺少選項所要求的值時,會自動打印一個錯誤消息到標准錯誤流中.設置成0的話,將不打印任何錯誤信息,但仍然返回”?”或”:”指明錯誤.

我感覺已經解釋的差不多了...寫完介紹突然覺得好麻煩...還不如自己寫函數分析.....

Linux進程控制——exec函數族 http://www.linuxidc.com/Linux/2013-04/82950.htm

Linux進程間通信 http://www.linuxidc.com/Linux/2013-06/85904.htm

Linux進程間通信:消息隊列 http://www.linuxidc.com/Linux/2013-01/78676.htm

Linux進程的基本知識 http://www.linuxidc.com/Linux/2011-12/48430.htm

二.環境變量

shell標准環境變量.

HOME 用戶的主目錄或初始默認目錄

LANG 對於地區設置的預定義的名字

LC_COLLATE 字符排序的地區類別名

LC_CTYPE 字符處理的地區類別名

LC_MONETARY 包含有關貨幣數字編輯信息的地區類別名

LC_NUMERIC 包含數字編輯信息(例如基字字符)的地區類別名

LC_TIME 日期/時間格式信息的地區類別名

LOGNAME 與當前進程相聯系的注冊名

PATH 可執行文件的路徑前綴

TERM 終端類型

TZ 時區信息



每個進程的環境表

extern char ** environ;這是進程的環境變量表指針.

其內容有HOME,PATH,SHELL,USER,LOGNAME這幾個環境變量.



訪問環境變量

char * getenv(const char *name);

int putenv(char *str);

第一個函數參數就是環境變量的名字.返回環境變量串指針.沒什麼好說的.

第二個函數則是增加一個環境變量或者去掉一個環境變量的定義.如果參數是name=value的形式.那麼就會增加一個環境變量.如果是name已存在,那麼就會把舊的定義去掉.同時設置為成新的值.並且不要以局部變量作為字符數組作為str的參數.



補充一點,實際上環境變量在進程虛擬地址空間中是在內核區中的.這一點我是看APUE和百度的一張圖結合起來發現的.原來以為環境變量是在棧段上面一個專門的位置空出來存放環境變量.但這幾天看書,發現並不是那麼一回事.看來自己原來記錯了.



三.終止進程

只學過語言的估計覺得在main裡面return就足夠了吧...但實際上多線程之後return在很多情況下就不合適了.就要用下面的函數了

int exit(int status);

可能有的人還見過_exit.實際上exit就是調用_exit來退出並且返回到內核的.但是實際上在返回到內核之前,還要執行一些清理工作.具體如下:

--按atexit()注冊時相反的順序調用所有注冊函數.

--關閉所有打開的流.

--刪除用tmpfile()建立的所有臨時文件.

--調用exit(status)終止進程.



這裡exit的status可以用兩個宏來定義.EXIT_SUCCESS和EXIT_FAILURE.其實就是0和1.



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

表示注冊一個函數,到進程正常終止時調用其注冊的函數.簡單來說相當於進程的析構函數.

我猜對於pthread應該是用atexit注冊了一個函數.所以在進程終止的時候就可以關閉線程了.並且查了才知道atexit最多只能注冊32個函數.但線程是很多的.估計只能這樣了.還有pthread_cleanup_push和pop好像就沒有上限限制.應該都是針對線程的注冊函數知道的一個變量來操作的吧.

貌似這裡可以搞一個惡作劇~可以注冊一個函數,這個函數裡面通過exec並且把路徑傳遞進去~那麼這個進程就永遠關不掉了~~~~~如果我要是黑客...我就會搞一下這個~用鉤子把原先的位置記錄下來,調用一個atexit,然後再把PC寄存器的值還回去~~~當然先得我學會用鉤子這種東西再說吧~~~



流產函數

void abort();

這個以執行立即終止程序.並且不用atexit注冊的清理函數.但在終止程序之前關閉所有打開的流並生成一個core文件.

所有異常終止程序的原因都是由信號造成的.實際上abort就是通過生成一個SIGABRT信號來流產的.

更多詳情見請繼續閱讀下一頁的精彩內容: http://www.linuxidc.com/Linux/2014-06/103325p2.htm

Copyright © Linux教程網 All Rights Reserved