實驗內容:
理髮店問題:假設理髮店的理髮室中有3個理髮椅子和3個理髮師,有乙個可容納4個顧客坐等理髮的沙發。此外還有一間等候室,可容納13位顧客等候進入理髮室。顧客如果發現理髮店中顧客已滿(超過20人),就不進入理髮店。在理髮店內,理髮師一旦有空就為坐在沙發上等待時間最長的顧客理髮,同時空出的沙發讓在等候室中等待時間最長的的顧客就坐。顧客理完發後,可向任何一位理髮師付款。但理髮店只有一本現金登記冊,在任一時刻只能記錄乙個顧客的付款。理髮師在沒有顧客的時候就坐在理髮椅子上睡眠。理髮師的時間就用在理髮、收款、睡眠上。請利用linux系統提供的ipc程序通訊機制實驗並實現理髮店問題的乙個解法。
二.實驗思路:
1.因為有三個理髮師和三把理髮椅,理髮師和理髮椅是一一對應的,所以可以忽略理髮椅而直接將它和理髮師視為一體,因為三個理髮師進行的是同樣的動作——理髮、睡眠和收款,所以需要利用fork()呼叫建立兩個子程序,和父程序一起用來分別代表三個理髮師。
2.因為開始沒顧客,所以理髮師一開始都直接進入休眠狀態。
3. 因為理髮店只有一本現金登記冊,在任一時刻只能記錄乙個顧客的付款,所以應設乙個互斥訊號量account_sem用來控制理髮師對登記冊的修改訪問。
4.因為沙發只有4個,等候室只能有13個人呆在裡面,所以要設兩個數sofa_count和wait_count,用來記錄當前在沙發上和在等候室裡的人數,以分別控制人數不超過要求。並且為防止多個程序同時對這兩個數進行修改造成混亂,應設定乙個互斥訊號量count_sem 用來控制程序對這兩個數的修改。
5.建立四個 訊息佇列sofa_quest_***,sofa_respond_***和
wait_quest_***,wait_respond_***;sofa_quest_***用來記錄當前請求剪髮的訊息,相當於擺在醫生桌面上的病例,理髮師通過檢查該訊息佇列來判斷有沒有顧客等待理髮,若沒有則睡眠。sofa_respond_***用來記錄理髮師完成剪髮的訊息。wait_quest_***用來記錄請求沙發座位的訊息,wait_respond_***用來記錄請求到沙發座位的訊息。如果理髮師空閒,則檢查sofa_quest_***看有沒有顧客等待理髮,如果沙發當前沒有坐滿則看等候室裡是否有人,有人則檢查wait_quest_***佇列來選取等候最久的人坐到沙發上。檢查sofa_respond_***佇列,如果裡面有訊息,則說明有顧客完成理髮,則把沙發當前的人數sofa_count減一;檢查wait_respond_***,如果裡面有訊息,則說明有顧客從等候室進入沙發,則把等候室當前的人數wait_count減一。
三.實驗結果:
ipc.h:
#include#include#include#include#include#include#include#define bufsz 256
#define writerquest 1
#define readerquest 2
#define finished 3
typedef union semunssem_uns;
typedef struct msgbufmsg_buf;
key_t account_key;
int account_sem;
key_t count_key;
int count_sem;
int sem_val;
int sem_***;
int wait_quest_***;
key_t wait_quest_key;
int wait_quest_id;
int wait_respond_***;
key_t wait_respond_key;
int wait_respond_id;
int sofa_quest_***;
key_t sofa_quest_key;
int sofa_quest_id;
int sofa_respond_***;
key_t sofa_respond_key;
int sofa_respond_id;
int get_ipc_id(char*proc_file,key_t key);
char*set_shm(key_t shm_key,int shm_num,int shm_flag);
int set_msq(key_t msq_key,int msq_flag);
int set_sem(key_t sem_key,int sem_val,int sem_flag);
int down(int sem_id);
int up(int sem_id);
ipc.c:
#include"ipc.h"
int get_ipc_id(char*proc_file,key_t key)
fgets(line,bufsz,pf);
while(!feof(pf))
fclose(pf);
return -1;
}int down(int sem_id)
return exit_success;
}int up(int sem_id)
return exit_success;
}int set_sem(key_t sem_key,int sem_val,int sem_***)
sem_arg.val=sem_val;
if(semctl(sem_id,0,setval,sem_arg)<0)
}return sem_id;
}char* set_shm(key_t shm_key,int shm_num,int shm_***)
if((shm_buf=(char*)shmat(shm_id,0,0))
for(i=0;i=0)
}}else if((pid2=fork())==0)
}}else}}
return exit_success;
}
customer.c:
#include"ipc.h"
int main(int argc,char* argv)
if(sofa_count<4)
else
down(count_sem);
sofa_count++;
up(count_sem);
}else if(wait_count<13)
else
wait_respond_***=ipc_nowait;
if(msgrcv(wait_respond_id,&msg_arg,sizeof(msg_arg),0,wait_respond_***)>=0)
sofa_respond_***=ipc_nowait;
if(msgrcv(sofa_respond_id,&msg_arg,sizeof(msg_arg),0,sofa_respond_***)>=0)
}return exit_success;
}
作業系統實驗五
16281271 巫勐 本實驗要求在模擬的i o系統之上開發乙個簡單的檔案系統。使用者通過create,open,read等命令與檔案系統互動。檔案系統把磁碟視為順序編號的邏輯塊序列,邏輯塊的編號為0至l 1。i o系統利用記憶體中的陣列模擬磁碟。實際物理磁碟的結構是多維的 有柱面 磁頭 扇區等概念...
作業系統實驗
一 實驗目的 理解vi的三種執行模式及其切方法。學會使用vi的各種操作命令進行文字檔案的編輯。用vi編寫linux下c程式,會用gcc編譯。二 實驗環境 一台裝有linux的機器 這裡預設是red hat linux 9 系統裡面有gcc編譯器。三 實驗內容 寫出主要的內容 首先用合法使用者登入系統...
作業系統實驗
分析bootloader進入保護模式的過程。在剛進入bootloader的時候,最先執行的操作分別為關閉中斷 清除eflags的df位以及將ax,ds,es,ss暫存器初始化為0 globl start start code16 cli 關中斷 cld 清除方向標誌 xorw ax,ax ax清0 ...