Linux學(xué)習(xí)
1.操作系統(tǒng)的實(shí)驗(yàn)基本上都是以linux下面的系統(tǒng)編程為內(nèi)容,進(jìn)程的調(diào)度和創(chuàng)建都是很基本的內(nèi)容。很幸運(yùn)的是,linux為我們提供了很多的系統(tǒng)函數(shù),供我們來(lái)使用。通過(guò)熟悉這些函數(shù),使得我們可以能夠?qū)M(jìn)程和程序有一個(gè)更良好的認(rèn)識(shí)。
2.Fork函數(shù)的使用。下面引用自百度百科:
|
fork()函數(shù),Linux系統(tǒng)調(diào)用
頭文件:
#include <unistd.h>
函數(shù)定義:
int fork( void );
返回值:
子進(jìn)程中返回0,父進(jìn)程中返回子進(jìn)程ID,出錯(cuò)返回-1
函數(shù)說(shuō)明:
一個(gè)現(xiàn)有進(jìn)程可以調(diào)用fork函數(shù)創(chuàng)建一個(gè)新進(jìn)程。由fork創(chuàng)建的新進(jìn)程被稱為子進(jìn)程(child process)。fork函數(shù)被調(diào)用一次但返回兩次。兩次返回的唯一區(qū)別是子進(jìn)程中返回0值而父進(jìn)程中返回子進(jìn)程ID。
子進(jìn)程是父進(jìn)程的副本,它將獲得父進(jìn)程數(shù)據(jù)空間、堆、棧等資源的副本。注意,子進(jìn)程持有的是上述存儲(chǔ)空間的“副本”,這意味著父子進(jìn)程間不共享這些存儲(chǔ)空間,它們之間共享的存儲(chǔ)空間只有代碼段。
示例代碼:
#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. 下面來(lái)詳細(xì)的說(shuō)說(shuō)我的程序和問(wèn)題,通過(guò)比較學(xué)習(xí),相信對(duì)于linux的學(xué)習(xí),特別是進(jìn)程和程序直接的關(guān)系有一個(gè)更好的理解。
Process2.c
Code:
#include <stdio.h>
#include <unistd.h>
int main()
{
int p1;
p1=fork();
if (p1 == 0) //子進(jìn)程,輸出它的父進(jìn)程和當(dāng)前進(jìn)程的PID
{
printf("current PID is %d\n",getpid());
printf("father PID is %d\n",getppid());
printf("\n");
}
else //這里是父進(jìn)程嗎?
{
printf("father PID is %d\n",getppid());
printf("current PID is %d\n",getpid());
printf("\n");
}
return 0;
}
分析:此進(jìn)程的運(yùn)行結(jié)果是?(思考后再回答)
是的,有兩種情況。首先,程序運(yùn)行到fork語(yǔ)句之后,創(chuàng)建進(jìn)程,此時(shí)有兩種情況,創(chuàng)建成功和不成功,而成功又有兩種情況,fork的返回值為0,則運(yùn)行的是創(chuàng)建的子進(jìn)程,fork的返回值為1,則運(yùn)行的是父進(jìn)程。用if語(yǔ)句來(lái)判斷,OK。
那么問(wèn)題就是,if語(yǔ)句中沒有問(wèn)題,p1為0,說(shuō)明創(chuàng)建成功,運(yùn)行的是子進(jìn)程,可是else語(yǔ)句來(lái)說(shuō),卻又兩種情況,如果創(chuàng)建不成功也在else語(yǔ)句中,那么此時(shí)當(dāng)前進(jìn)程就是那個(gè)原始的進(jìn)程,而它的父進(jìn)程卻是1號(hào)PID,因?yàn)樗械倪M(jìn)程都是1號(hào)進(jìn)程的子進(jìn)程,這個(gè)是linux下面的結(jié)論。操作系統(tǒng)的知識(shí)。
所以,此時(shí)的結(jié)果應(yīng)該是:
|
father PID is 32667
current PID is 15254
current PID is 15255
father PID is 1
|
先放著,先解釋下面的這個(gè),注意,這個(gè)對(duì)上面是有幫助的。
(看完之后回頭過(guò)來(lái)看看),看到?jīng)]有,首先輸出的那個(gè)father PID是什么,剛好就是下面的那個(gè)32667,這個(gè)不是偶然的,說(shuō)明什么,當(dāng)然,這個(gè)進(jìn)程就是父進(jìn)程,而創(chuàng)建它的那個(gè)進(jìn)程的PID是32667,可以認(rèn)為是系統(tǒng)創(chuàng)建的。就是說(shuō)這種情況下面是,先運(yùn)行的父進(jìn)程。而它創(chuàng)建失敗了,那么它沒有子進(jìn)程啊,那么那個(gè)下面的這個(gè)進(jìn)程的父進(jìn)程就不是上面的那個(gè)了,為何,從結(jié)果可以看到,它的PID是1,而不會(huì)是15254,說(shuō)明不是上面的那個(gè)創(chuàng)建。而創(chuàng)建卻是1,說(shuō)明是系統(tǒng)創(chuàng)建的,所以fork語(yǔ)句之后,沒有創(chuàng)建成功,而是由系統(tǒng)來(lái)親自創(chuàng)建一個(gè)進(jìn)程,所以PID號(hào)當(dāng)然是下一個(gè),不過(guò)父進(jìn)程就是1號(hào)了。(有興趣的可以查閱下資料,我們也是剛學(xué),所以我還有繼續(xù)探究中?。?/span>)
|
current PID is 15302 //子進(jìn)程
father PID is 15301[l1]
father PID is 32667 //父進(jìn)程
current PID is 15301
|
系統(tǒng)創(chuàng)建了當(dāng)前的那個(gè)父進(jìn)程,就是程序運(yùn)行的進(jìn)程
PID = 32667
|
下面還想討論這樣一個(gè)問(wèn)題,這個(gè)問(wèn)題是從上面那個(gè)第一種情況引申來(lái)的。
如下:
Code:
|
#include <stdio.h>
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]
|
結(jié)果如下,雖然比較多,不過(guò)很能說(shuō)明問(wèn)題:
|
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
|
看完了上面的那個(gè)例子,下面的這個(gè)例子就是小case了,當(dāng)然,其實(shí)上面的那個(gè)例子就是由下面的這個(gè)例子引申來(lái)的,是因?yàn)閷戝e(cuò)了代碼而引起的。當(dāng)然,根據(jù)錯(cuò)誤,我們收獲不小?。?/span>
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;
}
|
結(jié)果如下:
|
current PID is 20312[l3]
father PID is 20311
father PID is 32667
current PID is 20311
----------------------------------------------------------------------------------------------------------------
father PID is 32667
current PID is 20309[l4]
current PID is 20310
father PID is 1
|
[l1]父進(jìn)程的PID剛好就是下面的那個(gè)父進(jìn)程的current PID,說(shuō)明下面的那個(gè)進(jìn)程就是父進(jìn)程。
[l2]看看這個(gè)程序,雖然比較流氓,不過(guò)可以根據(jù)結(jié)果知道,如果創(chuàng)建失敗的話,那么也會(huì)有一個(gè)當(dāng)前的PID,而且還是由一個(gè)1號(hào)進(jìn)程創(chuàng)建。
[l3]當(dāng)前是子進(jìn)程,而它的父進(jìn)程恰好是下面的這個(gè)進(jìn)程!
[l4]父進(jìn)程就是這個(gè)進(jìn)程,而它的那個(gè)子進(jìn)程卻是由系統(tǒng)創(chuàng)建的!
后來(lái)通過(guò)查閱資料知道,如果父進(jìn)程創(chuàng)建一個(gè)子進(jìn)程后其先結(jié)束,那么子進(jìn)程就變成了孤兒進(jìn)程,這樣的話,就會(huì)由初始化進(jìn)程,即1號(hào)進(jìn)程來(lái)領(lǐng)養(yǎng)。所以會(huì)顯示它的父進(jìn)程為1.至此,完美的解決了。。
最近在看《Linux程序設(shè)計(jì)》(第三版)一書,收獲頗豐。本書是Linux下面程序設(shè)計(jì)的經(jīng)典,值得一睹。。而且最近的感觸是,懂得linux的操作和會(huì)在Linux下面進(jìn)程程序設(shè)計(jì)完全是兩回事,就像你會(huì)用windows和會(huì)開發(fā)windows下面的程序一樣。我輩任重而道遠(yuǎn)啊。。
posted on 2009-12-10 14:41
deercoder 閱讀(329)
評(píng)論(0) 編輯 收藏 引用 所屬分類:
C/C++