Linux學習
1.操作系統的實驗基本上都是以linux下面的系統編程為內容,進程的調度和創建都是很基本的內容。很幸運的是,linux為我們提供了很多的系統函數,供我們來使用。通過熟悉這些函數,使得我們可以能夠對進程和程序有一個更良好的認識。
2.Fork函數的使用。下面引用自百度百科:
fork()函數,Linux系統調用 頭文件: #include <unistd.h> 函數定義: int fork( void ); 返回值: 子進程中返回0,父進程中返回子進程ID,出錯返回-1 函數說明: 一個現有進程可以調用fork函數創建一個新進程。由fork創建的新進程被稱為子進程(child process)。fork函數被調用一次但返回兩次。兩次返回的唯一區別是子進程中返回0值而父進程中返回子進程ID。 子進程是父進程的副本,它將獲得父進程數據空間、堆、棧等資源的副本。注意,子進程持有的是上述存儲空間的“副本”,這意味著父子進程間不共享這些存儲空間,它們之間共享的存儲空間只有代碼段。 示例代碼: #include <unistd.h> #include <stdio.h> int main(int argc, void ** argv ) { int pid = fork(); if(pid == -1 ) { // print("error!"); } else if( pid = =0 ) { // print("This is the child process!"); } else { // print("This is the parent process! child process id = %d", pid); } return 0; } |
1. 下面來詳細的說說我的程序和問題,通過比較學習,相信對于linux的學習,特別是進程和程序直接的關系有一個更好的理解。
Process2.c
Code:
#include <stdio.h>
#include <unistd.h>
int main()
{
int p1;
p1=fork();
if (p1 == 0) //子進程,輸出它的父進程和當前進程的PID
{
printf("current PID is %d\n",getpid());
printf("father PID is %d\n",getppid());
printf("\n");
}
else //這里是父進程嗎?
{
printf("father PID is %d\n",getppid());
printf("current PID is %d\n",getpid());
printf("\n");
}
return 0;
}
分析:此進程的運行結果是?(思考后再回答)
是的,有兩種情況。首先,程序運行到fork語句之后,創建進程,此時有兩種情況,創建成功和不成功,而成功又有兩種情況,fork的返回值為0,則運行的是創建的子進程,fork的返回值為1,則運行的是父進程。用if語句來判斷,OK。
那么問題就是,if語句中沒有問題,p1為0,說明創建成功,運行的是子進程,可是else語句來說,卻又兩種情況,如果創建不成功也在else語句中,那么此時當前進程就是那個原始的進程,而它的父進程卻是1號PID,因為所有的進程都是1號進程的子進程,這個是linux下面的結論。操作系統的知識。
所以,此時的結果應該是:
father PID is 32667 current PID is 15254
current PID is 15255 father PID is 1 |
先放著,先解釋下面的這個,注意,這個對上面是有幫助的。
(看完之后回頭過來看看),看到沒有,首先輸出的那個father PID是什么,剛好就是下面的那個32667,這個不是偶然的,說明什么,當然,這個進程就是父進程,而創建它的那個進程的PID是32667,可以認為是系統創建的。就是說這種情況下面是,先運行的父進程。而它創建失敗了,那么它沒有子進程啊,那么那個下面的這個進程的父進程就不是上面的那個了,為何,從結果可以看到,它的PID是1,而不會是15254,說明不是上面的那個創建。而創建卻是1,說明是系統創建的,所以fork語句之后,沒有創建成功,而是由系統來親自創建一個進程,所以PID號當然是下一個,不過父進程就是1號了。(有興趣的可以查閱下資料,我們也是剛學,所以我還有繼續探究中!!)
current PID is 15302 //子進程
father PID is 32667 //父進程 current PID is 15301 |
PID = 13501 父進程 |
PID = 13504 子進程 |
系統創建了當前的那個父進程,就是程序運行的進程 PID = 32667 |
下面還想討論這樣一個問題,這個問題是從上面那個第一種情況引申來的。
如下:
Code:
int main() { int p1; while (( p1 = fork())!= -1); if (p1 == -1) { printf("current PID is %d\n",getpid()); printf("father PID is %d\n",getppid()); } return 0; }[l2] |
結果如下,雖然比較多,不過很能說明問題:
current PID is 17600 father PID is 1 current PID is 17761 father PID is 1 current PID is 17602 father PID is 1 current PID is 18545 father PID is 1 current PID is 17608 father PID is 1 current PID is 17767 father PID is 1 current PID is 17624 father PID is 1 current PID is 17773 father PID is 1 current PID is 17616 father PID is 1 current PID is 18551 father PID is 1 current PID is 17630 father PID is 1 current PID is 18552 father PID is 1 current PID is 17636 father PID is 1 current PID is 17779 father PID is 1 current PID is 17642 father PID is 1 current PID is 17785 father PID is 1 current PID is 17648 father PID is 1 current PID is 17787 father PID is 1 current PID is 17654 father PID is 1 current PID is 17795 father PID is 1 current PID is 18510 father PID is 1 current PID is 17801 father PID is 1 current PID is 18511 father PID is 1 current PID is 17807 father PID is 1 current PID is 17656 father PID is 1 current PID is 17815 father PID is 1 current PID is 17384 father PID is 32667 current PID is 17819 father PID is 1 current PID is 17660 father PID is 1 father PID is 1 current PID is 17825 father PID is 1 current PID is 17668 father PID is 1 current PID is 18571 father PID is 1 father PID is 1 father PID is 1 father PID is 1 father PID is 1 current PID is 17672 father PID is 1 current PID is 18572 father PID is 1 current PID is 17678 father PID is 1 current PID is 17831 father PID is 1 father PID is 1 current PID is 17684 father PID is 1 current PID is 17839 father PID is 1 current PID is 17690 father PID is 1 current PID is 17845 father PID is 1 current PID is 17696 father PID is 1 current PID is 17851 father PID is 1 current PID is 17702 father PID is 1 current PID is 17857 father PID is 1 current PID is 17710 father PID is 1 current PID is 17863 father PID is 1 current PID is 18531 father PID is 1 current PID is 17786 father PID is 1 current PID is 17714 father PID is 1 current PID is 18566 father PID is 17786 current PID is 17720 father PID is 1 current PID is 18533 father PID is 1 current PID is 17728 father PID is 1 current PID is 18538 father PID is 1 current PID is 17730 father PID is 1 current PID is 18548 father PID is 17740 current PID is 17738 father PID is 1 current PID is 17794 father PID is 1 current PID is 17740 father PID is 1 current PID is 17804 father PID is 1 current PID is 17750 father PID is 1 current PID is 17810 father PID is 1 current PID is 17756 father PID is 1 current PID is 17814 father PID is 1 current PID is 17764 current PID is 17820 father PID is 1 father PID is 1 current PID is 17768 father PID is 1 current PID is 17826 father PID is 1 current PID is 17774 father PID is 1 current PID is 17832 father PID is 1 current PID is 17780 father PID is 1 current PID is 17838 father PID is 17913 father PID is 1 father PID is 17929 father PID is 17927 father PID is 1 father PID is 17941 father PID is 1 father PID is 17950 father PID is 1 |
看完了上面的那個例子,下面的這個例子就是小case了,當然,其實上面的那個例子就是由下面的這個例子引申來的,是因為寫錯了代碼而引起的。當然,根據錯誤,我們收獲不小啊!
Code:
#include <stdio.h> #include <unistd.h> int main() { int p1; while ((p1=fork())==-1) ; if (p1 == 0) { printf("current PID is %d\n",getpid()); printf("father PID is %d\n",getppid()); printf("\n"); } else { printf("father PID is %d\n",getppid()); printf("current PID is %d\n",getpid()); printf("\n"); } return 0; } |
結果如下:
father PID is 20311
father PID is 32667 current PID is 20311
---------------------------------------------------------------------------------------------------------------- father PID is 32667
current PID is 20310 father PID is 1 |
[l1]父進程的PID剛好就是下面的那個父進程的current PID,說明下面的那個進程就是父進程。
[l2]看看這個程序,雖然比較流氓,不過可以根據結果知道,如果創建失敗的話,那么也會有一個當前的PID,而且還是由一個1號進程創建。
[l3]當前是子進程,而它的父進程恰好是下面的這個進程!
[l4]父進程就是這個進程,而它的那個子進程卻是由系統創建的!
后來通過查閱資料知道,如果父進程創建一個子進程后其先結束,那么子進程就變成了孤兒進程,這樣的話,就會由初始化進程,即1號進程來領養。所以會顯示它的父進程為1.至此,完美的解決了。。
最近在看《Linux程序設計》(第三版)一書,收獲頗豐。本書是Linux下面程序設計的經典,值得一睹。。而且最近的感觸是,懂得linux的操作和會在Linux下面進程程序設計完全是兩回事,就像你會用windows和會開發windows下面的程序一樣。我輩任重而道遠啊。。