您的位置:首页 > 运维架构 > Linux

Linux下生产者消费者问题详细分析(操作系统期中考试论文---并发程序的同步和互斥)

2011-12-23 23:45 751 查看
这是操作系统期中考试时我写的小论文,想要文档及代码的点击下载

要求如下:







本篇为了简洁,只贴有用的信息。

执行逻辑说明:

程序启动后首先初始化信号量集和循环缓冲队列。然后按照提示信息输入生产者数量和消费者数量。根据生产者和消费者数量创建相应的生产者线程和消费者线程。生产者线程执行生产者函数,向缓冲区放一个值,然后write指针加1。消费者执行消费者函数,从缓冲区读一个值,然后read指针加1。

源码如下:

/* pc.c:Producer and Consumer Problem
*author : houjialin
*To compile: g++ pc.c -o pc -l pthread
*/
#include<stdio.h>
#include<stdlib.h>//exit
#include<sys/types.h>
#include<sys/ipc.h>
#include<sys/sem.h>
#include<pthread.h>
#include <unistd.h>//sleep
#include<signal.h>
#define Maxbuf 10
//定义循环缓冲队列及对其的一组操作
struct Circlebuf//循环缓冲队列结构
{
int read;//读指针
int write;//写指针
int buf[Maxbuf];//缓冲区
} circlebuf;
void writeCirclebuf(Circlebuf *circlebuf,int *value)//向缓冲区中写一个值
{
circlebuf->buf[circlebuf->write]=(*value);
circlebuf->write=(circlebuf->write+1)%Maxbuf;//写过后指针+1

}
int  readCirclebuf(Circlebuf *circlebuf)//从当前指针读一个值,返回value
{
int value=0;
value=circlebuf->buf[circlebuf->read];
circlebuf->buf[circlebuf->read]=0; //读过后置0
circlebuf->read=(circlebuf->read+1)%Maxbuf;//读过后read+1
return value;
}
void OutCirclebuf(Circlebuf *circlebuf)
{
printf("Circlebuf value:");
for(int i=0;i<Maxbuf;i++)
{
printf("%d  ", circlebuf->buf[i]);
}
printf("\n");
}
//定义信号量及对其的操作
#define SEM_Key 4001 //信号量Key值
struct sembuf semaphore;//定义一个信号量
int semid;//信号量ID
bool initSembuf()//创建信号量集,并初始化
{
int sem=0;
if((semid=semget(SEM_Key,3,IPC_CREAT|0666))>=0)
{
sem=1;
semctl(semid,0,SETVAL,sem);//第0个信号量,初值为1,缓冲区互斥使用(mutex)
sem=10;
semctl(semid,1,SETVAL,sem);//第1个信号量,初值为10,当前空缓冲区数(empty)
sem=0;
semctl(semid,2,SETVAL,sem);//第2个信号量,初值为0,当前满缓冲区数(full)
return true;
}
else
return false;
}
//对信号量的PV操作
void Pmutex()
{
semaphore.sem_num=0;
semaphore.sem_op=-1;
semaphore.sem_flg=SEM_UNDO;
semop(semid,&semaphore,1);
}
void Vmutex()
{
semaphore.sem_num=0;
semaphore.sem_op=1;
semaphore.sem_flg=SEM_UNDO;
semop(semid,&semaphore,1);
}
void Pempty()
{
semaphore.sem_num=1;
semaphore.sem_op=-1;
semaphore.sem_flg=SEM_UNDO;
semop(semid,&semaphore,1);
}
void Vempty()
{
semaphore.sem_num=1;
semaphore.sem_op=1;
semaphore.sem_flg=SEM_UNDO;
semop(semid,&semaphore,1);
}
void Pfull()
{
semaphore.sem_num=2;
semaphore.sem_op=-1;
semaphore.sem_flg=SEM_UNDO;
semop(semid,&semaphore,1);
}
void Vfull()
{
semaphore.sem_num=2;
semaphore.sem_op=1;
semaphore.sem_flg=SEM_UNDO;
semop(semid,&semaphore,1);
}
void sigend(int sig)
{
semctl(semid, IPC_RMID, 0);
exit(0);
}
void * productThread(void *i)//生产者线程
{
int *n=(int *)i;
while(true)
{
Pempty();//①
Pmutex();//②
writeCirclebuf(&circlebuf,n);
printf("Producer %d succeeded put a value=%d into the circlebuf.\n",*n,*n);
OutCirclebuf(&circlebuf);
Vmutex();//③
Vfull();//④
}
}
void * consumerThread(void *i)//消费者
{
int *n=(int *)i;
int value=0;//消费品存放处
while(true)
{
Pfull();//⑤
Pmutex();//⑥
value=readCirclebuf(&circlebuf);
printf("The consumer %d succeful consume .The value is %d \n",*n,value);
Vmutex();//⑦
Vempty();//⑧
}
}
int main()
{
While(! initSembuf());//初始化信号量集
signal(SIGINT, sigend);
signal(SIGTERM, sigend);
int ConsNum=0,ProdNum=0,ret;//初始化生产者消费者数量
pthread_t  cpid,ppid;//线程ID
//初始化循环缓冲队列
circlebuf.read=circlebuf.write=0;
for(int i=0;i<Maxbuf;i++)
{
circlebuf.buf[i]=0;
}
printf("Please input the number of producter :");
scanf("%d",&ProdNum);
int *pro=new int[ProdNum];
printf("Please input the number of consumer :");
scanf("%d",&ConsNum);
int *con=new int[ConsNum];
for(int i=1;i<=ProdNum;i++)//启动生产者
{
ppid=i+100;//为了和消费者线程ID区别,每个线程号都加100
pro[i-1]=i;
ret=pthread_create(&ppid,NULL,productThread,(void *)&pro[i-1]);//
if(ret!=0)
{
printf("Create thread error");
exit(1);
}
}
for(int i=1;i<=ConsNum;i++)//启动消费者
{
cpid=i;
con[i-1]=i;
ret=pthread_create(&cpid,NULL,consumerThread,(void *)&con[i-1]);
if(ret!=0)
{
printf("Create thread error");
exit(1);
}
}
sleep(100000);//不让main线程停止
}

编程平台说明:

操作系统:Ubuntu11.04

编译器: g++

同步机制:采用Linux下的信号量机制实现并发进程间的同步和互斥。源程序建立的信号量集中有三个信号量。第一信号量初值为1,缓冲区互斥时使用。第二个初值为10,相当于当前可用空缓冲区数量。第三个初值为0,表示当前已放入产品的缓冲区数量。

静态条件说明和执行结果分析:

(由于格式换着太麻烦了,这里直接上图片了。)































内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐