今天開始學習關於程序的相關知識,參考的教材依然是周立功的《嵌入式linux開發教程(上冊)》,內容相當於第12章。因為沒多少機會寫**來體會,這部分內容可能會比較抽象,難以理解。總之乙個乙個來吧。
初識程序
1. 程序是乙個已經開始執行,但是還沒終止的程式例項。
2. 程序是乙個動態的實體,它是如何從靜態的程式轉換而來呢?
首先要建立乙個新的程序,然後在新程序中裝載程式檔案,並執行檔案的main函式
ps: 關於這個main函式比較有意思,通常它被作為程式的起點。main函式有三種原型定義:
int main()
int main(int argc, char *argv);
int main(int argc, char *argv, char *env);
來關注一下最後一種形式吧,因為他最全面嘛,搞懂了它就萬無一失了。三個引數:
第乙個是整形,代表命令列引數的數目
第二個是字元型指標陣列,大小不定。即它是若干個指向字元型變數的指標所構成的陣列。如果把命令的各個引數都當成字串,那麼這裡的每個元素都指向各個字串的首位址。注意,argv[0]這個元素指向的是程式的名稱。
第三個也是字元型指標陣列,大小不定。因為程式執行中,可能會有各種環境變數發生作用,這個陣列中各個元素分別指向各環境變數。還有個疑問(環境變數都是字串?)
3. 程序的狀態
比較多,我也記不清,總之來一張圖吧
使用命令 ps -aux 後,觀察stat列,第乙個字元就代表該程序當前狀態
4. 每個程序在建立時,都被核心分配乙個id,常被稱為pid。pid是乙個整型資料,當程序退出時,這個數值可以被**再利用。使用getpid()函式可以獲取當前程序的pid。
比如像這樣寫:
printf("current process pid is %d\n", getpid());
ps:我查了下,getpid這個函式的標頭檔案是unist.h
5. uid和gid
linux中每個使用者有乙個使用者id,稱為uid;每個使用者所在的組有乙個組id,稱為gid。為什麼要扯這個,他與程序有什麼關係?
這決定了程序的許可權。在linux中對不同的使用者和組進行了非常明確的許可權劃分,不同的使用者和組所具有的許可權是不同的。當執行乙個程式時,該程式會獲取當前使用者的uid和gid,並且以此來作為程序的許可權。
6. 父程序和子程序
程序可以建立新的程序,這兩者乙個是父乙個是子。因此父程序和子程序都是相對概念。
linux中,所有的程序如果都套用這個父子程序的概念,可以將它們組織成乙個樹狀結構。這棵大樹的根基是init程序。也就是說所有的程序都是通過它衍生出來的。
輸入 pstree命令可以以樹狀結構顯示所有程序,不過我在root許可權下這麼做了,發現根基並非init,而是systemd。上網查了下,init作為根基和systemd作為根基,可以說是兩種啟動方式。概念上是並列、平級的。用了乙個,另乙個就不需要用了。init是比較老的,而systemd比較新。init應該是類似序列的執行方式,而systemd是並行的執行。具體的暫時沒空去研究,以後再議吧。
7. 關於環境變數
上面提到了程序執行中需要用到環境變數,那麼如何獲取這些環境變數呢?方法有三
其一,就像上面講的那樣,使用main函式的第三個引數 char *env,注意陣列的最後乙個元素是null。像書上那樣寫個**測試下吧。
執行後,把一大溜的環境變數都列印了出來。
從列印的結果來反推,這是用puts一行行列印出了環境變數。因而這每一行都被視作字串,它們的首位址傳給了main函式的引數env。
其二,利用全域性變數environ,該變數是乙個指向字元型指標的指標,即 char **environ
教材上利用下面的**,也能實現和剛才一樣的效果:
關於這個environ全域性變數,我認為以下猜測應該是基本靠譜的:
其三,利用函式getenv函式獲取環境變數。
該函式的定義:
char *getenv(const char *name);
示例:char *env;
env = getenv("home");
8. 標準io
每個程序建立時,系統都會自動開啟3個檔案,標準輸入、標準輸出和標準錯誤輸出。既然是檔案就會有控制代碼,它們分別是0、1、2。
教材上指出:
但是我感覺,既然你已經知道了這三個檔案的控制代碼,如果需要用到的話。直接寫數字就好了呀,為什麼要整這麼麻煩,用巨集去替代呢~是不是也會偶發像上次使用open函式,指定生成檔案的許可權時一樣的問題:在系統版本公升級或者變遷的時候,因為底層實現**的改變,導致應用層只認這種助記符一樣的巨集。
Linux應用程式設計學習記錄(一)
今天學習了讀寫檔案函式的相關知識,參考的書籍是周立功寫的 嵌入式linux開發教程 上冊 第11.3節。1.open函式和creat函式 因為creat函式可以用open函式來實現,所以就不再去理會它了。關於open函式,記憶起來可以拆解成幾點 a 有int型返回值,返回的是所開啟檔案的控制代碼,或...
Linux應用程式設計學習記錄(二)
今天來繼續學習檔案操作的相關api。早上查了下資料,發現現在學的這些api隸屬於posix標準,posix翻譯過來就是可移植作業系統介面,在unix類系統中應用的十分廣泛。處理檔案的api還有很多別的標準,比如ansi c標準,它應該是標準c語言提供的庫函式。在別人的文章中看到,這二者比較起來的話,...
Linux應用程式設計學習記錄(三)
1.lseek函式 前兩次已經學過了write和read函式,這兩個函式在使用中可能存在對同乙個檔案多次操作的問題,因此不得不關注讀寫的起點是哪兒。假設有這麼乙個需求 乙個檔案中有6個字元,開啟檔案後我希望直接讀取第4個字元,這怎麼辦?顯然直接讀取是不行的了,你得移動讀寫起點。lseek函式就是為這...