生产者消费者问题
(3)程序代码(重要代码请注释)
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <semaphore.h>
/**************
***************/
#define PN 2 //生产者数
实验报告
四、实验原理:
利用进程间共享的信号量、互斥锁等控制线程的同步。
相关函数说明:
信号量
sem_t
sem_init信号量初始化)、sem_wait(信号量值减一)、sem_post(信号量值加一)
互斥量(线程)
pthread_mutex_t
pthread_mutex_init(互斥量初始化)
pthread_mutex_lock(互斥量加锁)
pthread_mutex_unlock(互斥量解锁)
线程和进程
pthread_t(线程)
pid_t(进程)
pthread_create(创建线程)
fork(创建进程)
pthread_join(等待线程结束)
waitpid(停止目前进程的执行,直到有信号来到或子进程结束)
五实验内容:
1、有一群生产者进程在生产产品,并将这些产品提供给消费者进程去消费。为使生产者进程与消费者进程能并发执行,在两者之间设置了一个具有n个缓冲区的缓冲池:生产者进程从文件中读取一个数据,并将它存放到一个缓冲区中;消费者进程从一个缓冲区中取走数据,并输出此数据。生产者和消费者之间必须保持同步原则:不允许消费者进程到一个空缓冲区去取产品;也不允许生产者进程向一个已装满产品且尚未被取走的缓冲区中投放产品。
2、创建3进程(或者线程)作为生产者,4个进程(或者线程)作为消费者。创建一个文件作为数据源,文件中事先写入一些内容作为数据。
3、生产者和消费者进程(或者线程)都具有相同的优先级。
六实验器材(设备、元器件)
(1)学生每人一台PC,安装WindowsXP/2000操作系统。
(2)局域网络环境。
(3)个人PC安装VMware虚拟机和Ubuntu系统。
七实验步骤
(1)实现哲学家就餐问题
(2)算法思想
在同一个进程地址空间内执行的两个线程生产者线程生产物品,然后将物品放置在一个空缓冲区中供消费者线程消费。消费者线程从缓冲区中获得物品,然后释放缓冲区。当生产者线程生产物品时,如果没有空缓冲区可用,那么生产者线程必须等待消费者线程释放出一个空缓冲区。当消费者线程消费物品时,如果没有满的缓冲区,那么消费者线程将被阻塞,直到新的物品被生产出来。
pthreadState = pthread_create(&procID[j], NULL, prochase, NULL);
if (pthreadState != 0){
printf("product%d creation failed \n", j);
exit(1);
}
}
for (i = 0; i < PN; i++){
pthread_join(prodID[i],NULL);
}
for (j = 0; j< CN; j++){
pthread_join(procID[j], NULL);
}
return 0;
}
void* product(){
int prodID = ++productID;
while (1){
sleep(1);
#define CN 3//消费者数
#define M 10//缓冲区数目
int in;//生产者指针
int out;//消费者指针
int buff[M] = { 0 };
int productID=0, prochaseID=0; //生产者消费者id
sem_t isFull;//信号量
sem_t isEmpty;
int state1=sem_init(&isEmpty,0,M);
int state2=sem_init(&isFull,0,0);
if (state1!=0||state2!=0){
printf("create sem is error");
exit(1);
}
for (i = 0; i < PN;i++){
pthreadState = pthread_create(&prodID[i],NULL,product,(void*)(&i));
if (pthreadState!=0){
printf("product%d creation failed \n", i);
exit(1);
}
}Байду номын сангаас
for (j = 0; j < CN;j++){
sem_post(&isFull);
}
}
void* prochase(){
int procID = ++prochaseID;
while (1){
sleep(1);
sem_wait(&isFull);
pthread_mutex_lock(&mutex);
out = out%M;
printf("prochase %d is prochase in %d /n", procID, out);
pthread_mutex_t mutex;//互斥信号量
void* product();
void* prochase();
void print();
int main(){
pthread_t prodID[PN];
pthread_t procID[CN];
int i = 0,j=0;
int pthreadState;
sem_wait(&isEmpty);
pthread_mutex_lock(&mutex);
in = in%M;
printf("producter %d is product in %d /n", prodID,in);
buff[in] = 1;
print();
in++;
pthread_mutex_unlock(&mutex);
}
八、实验及结果分析:
九、实验结论、心得体会和改进建议:
本次试验加深了我对于上课生产者消费者问题的理解,让我对线程之间的同步还有信号量的设置原理。
buff[out] = 0;
print();
out++;
pthread_mutex_unlock(&mutex);
sem_post(&isEmpty);
}
}
void print(){
int i = 0;
for (i = 0; i < M; i++)
printf("%d ",buff[i]);
printf("\n");