(1)在ubuntu下,用系統提供的sem_open()、sem_close()、sem_wait()和sem_post()等訊號量相關的系統呼叫編寫pc.c程式。
(2)在ubuntu上編譯並執行pc.c,檢查執行結果。
用printf()向終端輸出資訊是很自然的事情,但當多個程序同時輸出時,終端也成為了乙個臨界資源,需要做好互斥保護,否則輸出的資訊可能錯亂。
另外,printf()之後,資訊只是儲存在輸出緩衝區內,還沒有真正送到終端上,這也可能造成輸出資訊時序不一致。用fflush(stdout)可以確保資料送到終端。
本次實驗相較於往屆已極大地簡化,畢竟時間有限,所以不用在linux0.11下實現訊號量(裡面沒有sem_open()等系統呼叫,需要自己新增),僅需要在ubantu下執行生產者,消費者的相關程式。
首先介紹一下所需函式
int fseek(file *stream, long offset, int fromwhere);
函式設定檔案指標stream的位置。
如果執行成功,stream將指向以fromwhere為基準,偏移offset(指標偏移量)個位元組的位置,函式返回0。
如果執行失敗(比如offset超過檔案自身大小),則不改變stream指向的位置,函式返回乙個非0值。
size_t fread(void *buffer,size_t size,size_t count, file *stream );
buffer 是讀取的資料存放的記憶體的指標
size 是每次讀取的位元組數
count 是讀取次數
stream 是要讀取的檔案的指標
從乙個檔案流中讀資料,最多讀取count個元素,每個元素size位元組,如果呼叫成功返回實際讀取到的元素個數,如果不成功或讀到檔案末尾返回 0。
size_t fwrite(const void* buffer, size_t size, size_t count, file* stream);
(2)size:要寫入內容的單位元組數;
(3)count:要進行寫入size位元組的資料項的個數;
(4)stream:目標檔案指標;
(5)返回實際寫入的資料項個數count。
演算法的思想是:建立乙個檔案緩衝區,0~9位儲存生產出的資料,第10位儲存當前讀到的位置;因為緩衝區是覆蓋寫入,例如當消費者消費到第6位,而生產者此時可以生產覆蓋前5位,但消費者消費是順序消費的,必須要讀到緩衝區尾才可以再從頭讀。
這就有必要儲存當前讀取的位置(因為程序可能被中斷,下次再來就不知道讀到**了),所以下面要執行兩次,第一次讀出當前所讀位置,再根據此位置計算位偏移。
fseek( fp, 10*sizeof(int), seek_set );
fread( &outpos, sizeof(int), 1, fp);
fseek( fp, outpos*sizeof(int), seek_set );
fread( &costnum, sizeof(int), 1, fp);
pc.c
#define __library__
#include #include #include #include #include #include #include #define total 500
#define pnum 5
#define buffersize 10
/**/
int main()
exit(0);
}for( k = 0; k < pnum ; k++ )
exit(0);}}
wait(null);
wait(null);
wait(null);
wait(null);
wait(null);
sem_unlink("empty");
sem_unlink("full");
sem_unlink("mutex");
fclose(fp);
return 0;
}
附report
1.在pc.c中去掉所有與訊號量有關的**,再執行程式,執行效果有變化嗎?為什麼會這樣?
答:在去掉與訊號量有關的**後,執行結果customer的消費資料沒有按遞增的順序輸出,且fread()函式將產生錯誤。
因為沒有訊號量p(s)控制,導致生產者可能在緩衝區滿後繼續生產,導致沒有被消費的資料被覆蓋,使得消費者消費的資料不是遞增序列。
同時,沒有訊號量v(s)控制,導致消費者可能在讀取所有資料後仍然繼續讀取,導致讀取的資料無效。
沒有mutex訊號量控制導致出現多程序併發訪問緩衝區,導致出現fread()錯誤。
2.這樣可行嗎?如果可行,那麼它和標準解法在執行效果上會有什麼不同?如果不可行,那麼它有什麼問題使它不可行?
答:這樣不可行。程式在某種情況下會出現死鎖狀態。
例如:當mutex = 1,並且生產者要進入生產乙個資料,假設此時empty = 0,mutex = 0,p(empty)後小於0,生產者程序進入等待在訊號量empty的等待佇列上面呼叫schedule(),
可是此時並未解鎖,即mutex.value值仍然為0。它們都等待在訊號量mutex上面。同理,消費者程序也是如此,若mutex.value = 1,full.value = 0,
在執行完p(mutex)p(full)之後,mutex = 0,並且將消費者程序放入等待在訊號量full的等待佇列上面,而此時也並未釋放mutex,
因此消費者和生產者程序都等待在mutex訊號量上面。進而產生飢餓狀態進入死鎖。
作業系統 程序同步
臨界資源 critical resouce 臨界區 critical section 硬體同步機制 訊號量機制 訊號量的應用 管程3使用多道批處理系統不僅能有效的改善資源的利用率,還可以顯著地提高系統的吞吐量,但同時會使系統變得更加複雜,會使程式的執行結果存在不確定性。所以必須引入程序同步機制從而保...
作業系統 程序同步
引入程序 提高了資源的利用率和系統的吞吐量 程序的非同步性 會給系統造成混亂 程序同步基本概念 1,兩種形式的制約關係 a 間接相互制約 ab兩程序爭用一台印表機 b 直接相互制約 a程序放資料 緩衝區 b程序從緩衝區取資料 2,臨界資源 硬體臨界資源 軟體臨界資源 印表機,磁帶機,緩衝區。3,臨界...
作業系統 程序同步
ipc.件 include include include include include include include define bufsz 256 建立或獲取 ipc 的一組函式的原型說明 int get ipc id char proc file,key t key char set s...