資源簡介
使用信號量實現(xiàn)有限緩沖區(qū)的生產(chǎn)者和消費者問題
使用信號量實現(xiàn)讀進程具有優(yōu)先權(quán)的讀者和寫者問題
實驗報告(內(nèi)容、環(huán)境、遇到的問題及解決、源代碼、流程圖、總結(jié))
源代碼

代碼片段和文件信息
#include?
#include?
#include?
#include?
#include?
#include?
#include?
#include?
#define?PRODUCER?1?//宏定義生產(chǎn)者個數(shù),?2個
#define?COSTOMER?12?//宏定義消費者個數(shù),?3個
#define?WRITE_NUM?12//宏定義寫緩沖次數(shù),?6次
#define?READ_NUM?1?//宏定義讀緩沖次數(shù),?4次
#define?SEM_ALL_KEY?1342
#define?SEM_EMPTY?0
#define?SEM_FULL?1
#define?BUF_LENGTH?(sizeof(struct?container_buffer))?//宏定義緩沖區(qū)大小
#define?BUFFER_NUM?4?//宏定義緩沖區(qū)個數(shù)?,?3個
#define?SHM_MODE?0600?//宏定義創(chuàng)建和訪問標志
//緩沖區(qū)結(jié)構(gòu)(循環(huán)隊列)
struct?container_buffer?//定義共享緩沖區(qū)結(jié)構(gòu)
{
char?letter[BUFFER_NUM];
int?head;
int?tail;
int?is_empty;?//判斷緩沖區(qū)是否為空的標志
};
//得到6以內(nèi)的一個隨機數(shù),產(chǎn)生延遲時間
int?random_num()
{
int?t;
srand((unsigned)(getpid()?+?time(NULL)));
t?=?rand()?%?4;
return?t;
}
//semWait操作,獲得使用權(quán)
void?semWait(int?sem_id?int?sem_num)
{
struct?sembuf?sem_buff;
sem_buff.sem_num?=?sem_num;
sem_buff.sem_op?=?-1;
sem_buff.sem_flg?=?0;
semop(sem_id?&sem_buff?1);
}
//得到一個隨機字符模擬產(chǎn)品名字
char?random_letter()
{
char?a;
srand((unsigned)(getpid()?+?time(NULL)));
a?=?(char)((char)(rand()?%?26)?+?‘a(chǎn)‘);
return?a;
}
//semSignal操作,釋放使用權(quán)
void?semSignal(int?sem_id?int?sem_num)
{
struct?sembuf?sem_buff;
sem_buff.sem_num?=?sem_num;
sem_buff.sem_op?=?1;
sem_buff.sem_flg?=?0;
semop(sem_id?&sem_buff?1);
}
//主函數(shù)
int?main(int?argc?char?*?argv[])
{
int?shm_id?sem_id;?//定義共享內(nèi)存段標識變量shm_id,定義信號量標識變量sem_id
int?num_p?=?0?num_c?=?0?i?j;?//定義生產(chǎn)者和消費者的個數(shù)變量,初始化為0
struct?container_buffer?*?shmptr;?//指向緩沖區(qū)結(jié)構(gòu)的指針
char?pn;?//隨機字符,代表產(chǎn)品
pid_t?pid_p?pid_c;?//進程pid變量
printf(“start...\n“);
sem_id?=?semget(SEM_ALL_KEY?2?IPC_CREAT?|?0660);?//創(chuàng)建兩個信號量?empty?full
semctl(sem_id?SEM_EMPTY?SETVAL?BUFFER_NUM);
//索引為SEM_EMPTY的信號量值為3
semctl(sem_id?SEM_FULL?SETVAL?0);
//索引為SEM_FULL的信號量值為0
if?((shm_id?=?shmget(IPC_PRIVATE?BUF_LENGTH?SHM_MODE))?0)
//申請一個共享主存段大小為緩沖區(qū)大小
{
printf(“申請一個共享主存段失敗\n“);
exit(1);?//失敗退出
}
if?((shmptr?=?shmat(shm_id?0?0))?==?(void?*)-1)?//將共享段與進程相連
{
printf(“將共享段與本進程相連失敗\n“);
exit(1);?//失敗退出
}
shmptr->head?=?0;?//初始化緩沖區(qū)
shmptr->tail?=?0;
shmptr->is_empty?=?1;
for(;num_p {
if?((pid_p?=?fork())?0)?//創(chuàng)建一個進程
{
printf(“創(chuàng)建子進程失敗\n“);
exit(1);?//失敗退出
}
//如果是子進程,開始創(chuàng)建生產(chǎn)者
if?(pid_p?==?0)
{
if?((shmptr?=?shmat(shm_id?0?0))?==?(void?*)-1)?//將共享段與本進程相連
{
printf(“將共享段與本進程相連失敗\n“);
exit(1);?//失敗退出
}
for?(i?=?0;?i? {
semWait(sem_id?SEM_EMPTY);?//semWait操作,申請使用權(quán)semWait(empty)
sleep(random_num());?//隨機等待一段時間
shmptr->letter[shmptr->tail]?=?pn?=?random_letter();
//在緩沖隊列里面放入一個產(chǎn)品
shmptr->tail?=?(shmptr->tail?+?1)?%?BUFFER_NUM;
shmptr->is_empty?=?0;
//更新緩沖區(qū)狀態(tài)為滿
printf(“生產(chǎn)者%d生產(chǎn)產(chǎn)品%c\t當前緩沖區(qū)為:?“num_p?pn);?//輸出動作序列
for?(j?=?(shmptr->tail?-?1?>=?shmptr->head)??(shmptr->tail?-?1)?:?(shmptr->tail?-?1?+?BUFFER_NUM);?!(shmptr->is_empty)&&?j?>=?shmptr->head;?j--)
//輸出緩沖區(qū)狀態(tài)
{
printf(“%c“?shmptr->letter
?屬性????????????大小?????日期????時間???名稱
-----------?---------??----------?-----??----
?????文件????????5776??2017-12-24?17:41??producer_consumer.c
?????文件??????538674??2017-12-24?17:22??實驗報告.docx
?????文件????????2711??2017-12-24?17:40??reader_writer.c
評論
共有 條評論