FZU作業系統課程實驗實驗一

來源:互聯網
上載者:User

自己的理解,不一定對,僅供參考,勿copy哦!雷同就一起掛了

實驗1

【實驗名稱】:並發程式設計(實驗1)

【實驗目的】:掌握在程式中建立新進程的方法, 觀察並理解多道程式並發執行的現象。

【實驗原理】:fork():建立子進程。子進程得到父進程地址空間的一個複製。

傳回值:成功時,該函數被調用一次,但返回兩次,fork()對子進程返回0,對父進程返回子進程標識符(非0值)。不成功時對父進程返回-1,沒有子進程。

【實驗內容】:首先分析一下程式運行時其輸出結果有哪幾種可能性,然後實際調試該程式觀察其實際輸出情況,比較兩者的差異,分析其中的原因。

void main (void)

{

int x=5;

if( fork( ) )

{

x+=30;

printf (“%d\n”,x);

}

else

printf(“%d\n”,x);

printf((“%d\n”,x);

}

【實驗要求】:每個同學必須獨立完成本實驗、提交實驗報告、來源程式和可執行程式。實驗報告中必須包含預計的實驗結果,關鍵代碼的分析,調試記錄,實際的實驗結果,實驗結果分析等內容。

一.關鍵程式碼分析

一個現有進程可以調用fork函數建立一個新進程。由fork建立的新進程被稱為子進程(child process)。fork函數被調用一次但返回兩次。兩次返回的唯一區別是子進程中返回0值而父進程中返回子進程ID。

子進程是父進程的副本,它將獲得父進程資料空間、堆、棧等資源的副本。注意,子進程持有的是上述儲存空間的“副本”,這意味著父子進程間不共用這些儲存空間。

也就是說,當程式運行到if條件判斷運行fork()函數後,父進程啟動並執行是條件成立成立的代碼,即

x+=30;

printf (“%d\n”,x);

子進程啟動並執行是條件不成立的代碼,即

printf(“%d\n”,x);

根據並發執行的工作方式及特徵,我們預計可能的實驗結果如下:

二.預計實驗結果

猜測有6種情況(其實就是這4個數的全排列)

35

35

35

5

5

5

35

5

5

5

35

35

5

35

5

35

5

35

5

5

35

35

35

5

三.調試記錄

1. 先建立一個.c為尾碼的文檔,如test.c

2. 編輯來源程式:

#include<stdio.h>

#include<unistd.h>

void main (void)

{

int x=5;

if( fork( ) )

{

x+=30;

printf (“%d\n”,x);

}

else

printf(“%d\n”,x);

printf((“%d\n”,x);

}

3. 在命令列下編輯 gcc –o test.out test.c

然後編輯 ./test.out

運行程式

4. 實際實驗結果:

35

35

(一串字元命令,省略)5

5

(PS:那段字元命令,父進程運行完就會出現,所以都是在輸出兩個35後出現)

重複步驟3,N次後發現還是這個結果。

四.實驗結果分析

老師說其它結果的出現是小機率事件。我們不敢苟同,這都基本上可以當不可能事件處理了。

於是我們猜測,這個跟傳說中的時間片有關。

因為這個程式運行所需的時間實在是太短,預設先啟動並執行父進程完全可以在系統給定的時間片內運行完,如果沒有出現什麼其他情況而掛起,子進程就只能等到父進程運行完後才能運行。

所以呢,當然就只有一種情況了。

五.實驗結果處理

不過,我們可以利用時間片的特性製造出6種結果。

主角登場了,sleep(1) 延時一秒函數

可以把延時函數理解為一段要運行1秒的代碼。下面的提到的進程,都是因在這段延時代碼中運行時進程時間片用完掛起(假設在這個延時代碼中運行了0.6秒),再次調度回來時,只要再運行0.4秒就可以了跳出這個延時函數了。

第一種:

因為預設先啟動並執行是父進程(我用的系統是這樣),我們感覺對子進程太不公平了,所以我們製造的第一種情況的源碼是:

#include<stdio.h>

#include<unistd.h>

void main (void)

{ int x=5;

if( fork( ) )

{

x+=30;

sleep(1);

printf (“%d\n”,x);

}

else

printf(“%d\n”,x);

printf((“%d\n”,x);

}

我們猜測時間片是0.6秒,不管對不對,重點是分析。

父進程運行0.6秒後,時間片用完掛起,調度運行子進程,子進程運行完後調度回父進程接著運行。所以我們猜測結果是

5

5

35

35

(一串字元命令,省略)

哇塞,運行完也是!

第二種:

這裡我們突然想到如果在子進程前也加個延時函數會怎樣,

#include<stdio.h>

#include<unistd.h>

void main (void)

{ int x=5;

if( fork( ) )

{

x+=30;

sleep(1);

printf (“%d\n”,x);

}

else {

sleep(1);

printf(“%d\n”,x);

}

printf((“%d\n”,x);

}

不過,這個只能調試完再根據答案去分析,因為我們也不知道真正的時間片是多少,只是猜測。運行結果為

35

35

(一串字元命令,省略)5

5

我們繼續假設時間片為0.6秒,父進程運行0.6秒後掛起,輪到子進程運行0.6秒後也掛起,調度回父進程繼續運行,因為之前已經運行了0.6秒,所以這次調度時間片就夠用了。假設成立

 

所以,以下都是假設時間片為0.6秒,這個時間是很合理的。

第三種:

#include<stdio.h>

#include<unistd.h>

void main (void)

{

int x=5;

if( fork( ) )

{

x+=30;

sleep(1);

printf (“%d\n”,x);

}

else {

printf(“%d\n”,x);

sleep(1);

}

printf((“%d\n”,x);

}

與前面的分析類似,父進程運行0.6秒後掛起,調度子進程會先運行第一條指令輸出x為5,然後進入延時函數運行0.6秒(前面運行1條指令的時間可以忽略不計)後掛起,調度回父進程運行完,再調度回子進程。所以輸出為

5

35

35

(一串字元應該是提示輸入的命令,省略)5

 

第四種:

#include<stdio.h>

#include<unistd.h>

void main (void)

{ int x=5;

if( fork( ) )

{

x+=30;

printf (“%d\n”,x);

sleep(1);

}

else {

printf(“%d\n”,x);

sleep(1);

}

printf((“%d\n”,x);

}

分析同上,輸出結果為

35

5

35

(一串字元命令,省略)5

第五種:

#include<stdio.h>

#include<unistd.h>

void main (void)

{ int x=5;

if( fork( ) )

{

x+=30;

printf (“%d\n”,x);

sleep(1);

}

else {

printf(“%d\n”,x);

}

printf((“%d\n”,x);

}

運行結果為,

35

5

5

35

(一串字元命令,省略)

第六種:

仔細看下上面5種情況,會發現還有種比較奇葩的沒有出現。

5

35

5

35

(一串字元命令,省略)

需要從父進程(延時掛起)->子進程(輸出然後延時掛起)->父進程(延時然後輸出然後再延時掛起)->子進程(輸出結束進程)->父進程(延時然後輸出結束進程),代碼為

#include<stdio.h>

#include<unistd.h>

void main (void)

{ int x=5;

if( fork( ) )

{

x+=30;

sleep(1);

printf (“%d\n”,x);

sleep(1);

}

else {

printf(“%d\n”,x);

sleep(1);

}

printf((“%d\n”,x);

}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.