用多线程实现“生产者-消费者问题”(代码+实验报告)
2008-11-25 20:37
597 查看
[/b]
用多线程实现“生产者-消费者问题”(代码+实验报告)[/b]
[/b]
#include <iostream>
#include <stdlib.h>
#include <STDIO.H>
#include <windows.h>
using namespace std;
typedef int semaphore; /* 信号量是一种特殊的整型变量 */
const int SIZE_OF_BUFFER = 5 ; //缓冲区长度
const unsigned short PRODUCERS_COUNT = 2; //生产者的个数
const unsigned short CONSUMERS_COUNT = 3; //消费者的个数
DWORD producers[PRODUCERS_COUNT] ; //生产者线程的标识符
DWORD consumers[CONSUMERS_COUNT] ;//消费者线程的标识符
const unsigned short THREADS_COUNT = PRODUCERS_COUNT+CONSUMERS_COUNT; //总的线程数
/**
*定义信号量
*/
HANDLE mutex ; //互斥信号量
HANDLE full ; //表示放有产品的缓冲区数,其初值为0
HANDLE empty ; //表示可供使用的缓冲区数,其初值为N
/**
*定义共享缓冲区
*/
semaphore buffer[SIZE_OF_BUFFER];
/**
*定义生产者和消费者使用的指针
*/
int in = 0 ;
int out = 0 ;
int productNum = 0 ;
DWORD WINAPI Producer(LPVOID) ;
DWORD WINAPI Consumer(LPVOID) ;
int main(int argc, char *argv[])
{
//创建Mutex和Semaphore
mutex = CreateMutex(NULL,FALSE,NULL);
full = CreateSemaphore(NULL,0,SIZE_OF_BUFFER,NULL);
empty = CreateSemaphore(NULL,SIZE_OF_BUFFER,SIZE_OF_BUFFER,NULL);
HANDLE PVThreads[THREADS_COUNT]; //各线程的handle
//创建生产者线程
for (int i=0;i<PRODUCERS_COUNT;i++){
PVThreads[i] = CreateThread(NULL,0,Producer,NULL,0,&producers[i]);
if (PVThreads[i] == NULL) break;
}
//创建消费者线程
for (int i=0;i<CONSUMERS_COUNT;i++){
PVThreads[PRODUCERS_COUNT+i]
=CreateThread(NULL,0,Consumer,NULL,0,&consumers[i]);
if (PVThreads[i]==NULL) break;
}
bool isContinue = true ;
while(isContinue)
{
if(getchar()){ //按回车后终止程序运行
isContinue = false;
}
}
system("PAUSE");
return 0;
}
void enBuffer(int pos)
{
cout<<"正在生产产品..."<<endl ;
Sleep(2000) ;
buffer[pos] = -1 ;
productNum++ ;
cout<<"生产完成! 已生产"<<productNum<<"个产品,并将新产品放在了缓冲区位置:"<<pos<<endl ;
}
void deBuffer(int pos)
{
cout<<"正在消费产品..."<<endl ;
Sleep(1000) ;
buffer[pos] = -2 ;
productNum-- ;
cout<<"已消费在缓冲区位置:"<<pos<<"的产品,缓冲区剩余空间:"<<SIZE_OF_BUFFER-productNum<<endl ;
cout<<endl ;
}
/**
*生产者
*/
DWORD WINAPI Producer(LPVOID lpParam )
{
while(1)
{
WaitForSingleObject(empty,INFINITE); // P(empty) 生产者信号量 -1
WaitForSingleObject(mutex,INFINITE); // P(mutex) 获取线程间互斥信号
enBuffer(in) ;
Sleep(1000) ;
in = (in+1)%SIZE_OF_BUFFER ;
ReleaseMutex(mutex); // V(mutex) 释放线程间互斥信号
ReleaseSemaphore(full,1,NULL); // V(full) 消费者信号量 +1
}
return 0;
}
/**
*消费者
*/
DWORD WINAPI Consumer(LPVOID lpPara)
{
while(1)
{
WaitForSingleObject(full,INFINITE)== WAIT_ABANDONED ; //P(full) 消费者信号量-1
WaitForSingleObject(mutex,INFINITE); //P(mutex) 获得线程间互斥信号
deBuffer(out) ;
Sleep(1000) ;
out = (out+1)%SIZE_OF_BUFFER ;
ReleaseMutex(mutex); //V(mutex) 释放线程间互斥信号
ReleaseSemaphore(empty,1,NULL); //V(empty) 生产者信号量+1
}
return 0;
}
北航软件学院《一级实践》实验报告
学号:GS0821594 姓名:叶现一 第 11 周[/b]
注意:实验报告和案例源代码须在本次小组讨论会前提交[/b]
用多线程实现“生产者-消费者问题”(代码+实验报告)[/b]
[/b]
#include <iostream>
#include <stdlib.h>
#include <STDIO.H>
#include <windows.h>
using namespace std;
typedef int semaphore; /* 信号量是一种特殊的整型变量 */
const int SIZE_OF_BUFFER = 5 ; //缓冲区长度
const unsigned short PRODUCERS_COUNT = 2; //生产者的个数
const unsigned short CONSUMERS_COUNT = 3; //消费者的个数
DWORD producers[PRODUCERS_COUNT] ; //生产者线程的标识符
DWORD consumers[CONSUMERS_COUNT] ;//消费者线程的标识符
const unsigned short THREADS_COUNT = PRODUCERS_COUNT+CONSUMERS_COUNT; //总的线程数
/**
*定义信号量
*/
HANDLE mutex ; //互斥信号量
HANDLE full ; //表示放有产品的缓冲区数,其初值为0
HANDLE empty ; //表示可供使用的缓冲区数,其初值为N
/**
*定义共享缓冲区
*/
semaphore buffer[SIZE_OF_BUFFER];
/**
*定义生产者和消费者使用的指针
*/
int in = 0 ;
int out = 0 ;
int productNum = 0 ;
DWORD WINAPI Producer(LPVOID) ;
DWORD WINAPI Consumer(LPVOID) ;
int main(int argc, char *argv[])
{
//创建Mutex和Semaphore
mutex = CreateMutex(NULL,FALSE,NULL);
full = CreateSemaphore(NULL,0,SIZE_OF_BUFFER,NULL);
empty = CreateSemaphore(NULL,SIZE_OF_BUFFER,SIZE_OF_BUFFER,NULL);
HANDLE PVThreads[THREADS_COUNT]; //各线程的handle
//创建生产者线程
for (int i=0;i<PRODUCERS_COUNT;i++){
PVThreads[i] = CreateThread(NULL,0,Producer,NULL,0,&producers[i]);
if (PVThreads[i] == NULL) break;
}
//创建消费者线程
for (int i=0;i<CONSUMERS_COUNT;i++){
PVThreads[PRODUCERS_COUNT+i]
=CreateThread(NULL,0,Consumer,NULL,0,&consumers[i]);
if (PVThreads[i]==NULL) break;
}
bool isContinue = true ;
while(isContinue)
{
if(getchar()){ //按回车后终止程序运行
isContinue = false;
}
}
system("PAUSE");
return 0;
}
void enBuffer(int pos)
{
cout<<"正在生产产品..."<<endl ;
Sleep(2000) ;
buffer[pos] = -1 ;
productNum++ ;
cout<<"生产完成! 已生产"<<productNum<<"个产品,并将新产品放在了缓冲区位置:"<<pos<<endl ;
}
void deBuffer(int pos)
{
cout<<"正在消费产品..."<<endl ;
Sleep(1000) ;
buffer[pos] = -2 ;
productNum-- ;
cout<<"已消费在缓冲区位置:"<<pos<<"的产品,缓冲区剩余空间:"<<SIZE_OF_BUFFER-productNum<<endl ;
cout<<endl ;
}
/**
*生产者
*/
DWORD WINAPI Producer(LPVOID lpParam )
{
while(1)
{
WaitForSingleObject(empty,INFINITE); // P(empty) 生产者信号量 -1
WaitForSingleObject(mutex,INFINITE); // P(mutex) 获取线程间互斥信号
enBuffer(in) ;
Sleep(1000) ;
in = (in+1)%SIZE_OF_BUFFER ;
ReleaseMutex(mutex); // V(mutex) 释放线程间互斥信号
ReleaseSemaphore(full,1,NULL); // V(full) 消费者信号量 +1
}
return 0;
}
/**
*消费者
*/
DWORD WINAPI Consumer(LPVOID lpPara)
{
while(1)
{
WaitForSingleObject(full,INFINITE)== WAIT_ABANDONED ; //P(full) 消费者信号量-1
WaitForSingleObject(mutex,INFINITE); //P(mutex) 获得线程间互斥信号
deBuffer(out) ;
Sleep(1000) ;
out = (out+1)%SIZE_OF_BUFFER ;
ReleaseMutex(mutex); //V(mutex) 释放线程间互斥信号
ReleaseSemaphore(empty,1,NULL); //V(empty) 生产者信号量+1
}
return 0;
}
北航软件学院《一级实践》实验报告
学号:GS0821594 姓名:叶现一 第 11 周[/b]
内容 训练 | 用多线程实现“生产者-消费者问题”[/b] | |||||
解决该问题的思路 | 假设有一组(多个)生产者和一组(多个)消费者,生产者负责生产物品,然后将物品放置在一个缓冲区中供消费者消费。消费者从缓冲区取走物品。假定缓冲区共有N个,不妨把它们设想成一个环形缓冲池。如下图所示: 其中,阴影部分表示该缓冲区中放有的产品,否则为空。In表示生产者下次存入产品的单元;out表示消费者下次取出产品的单元。 1) 为使这两类进程协调工作,防止盲目的生产和消费,它们应满足如下同步条件:任一时刻所有生产者存放产品的单元数不能超过缓冲区的总容量(N)。 2) 所有消费者取出产品的总量不能超过所有生产者当前生产产品的总量。 设缓冲区的编号为0~N-1,in和out分别是生产者进程和消费者进程使用的指针,指向下面可用的缓冲区,初值都是0。 为使两类进程实行同步操作,应设置三个信号量:两个计数信号量full和empty,一个互斥信号量mutex。 full:表示放有产品的缓冲区数,其初值为0。 empty:表示可供使用的缓冲区数,其初值为N。 mutex:互斥信号量,初值为1表示各进程互斥进入临界区,保证任何时候只有一个进程使用缓冲区。 下面是解决这个问题的算法描述。
1) 在每个程序中坐须先做P(mutex),后做V(mutex),二者要成对出现。夹在二者中间的代码段就是该进程的监界区。 2) 对同步信号量full和empty的P,V操作同样必须成对出现,但它们分别位于不同的程序中。 3) 无论在生产者进程中还是在消费者进程中,两个P操作的次序不能颠倒:应先执行同 步信号量的P操作,然后执行互斥信号量的P操作。否则可能造成进程死锁。 | |||||
本周开发源代码 | 代码的功能简述 | 用多线程实现“生产者-消费者问题” | ||||
开发的收获 | 关于Windows多线程API的使用; 深入了解了进程互斥问题 | |||||
开发中碰到的主要困难 | 1) 关于Windows多线程API的使用: 2) “生产者-消费者问题”问题的实现机制 | |||||
开发中未能解决的问题 | — | |||||
针对本周训练内容自己设计的案例 | 案例的主要功能 | 多线程实现“生产者-消费者问题” | ||||
用到的基本知识 | 进程同步与互斥原理;临界资源和临界区的相关定义;几种互斥的实现方式;关于信号量的使用及其实现方式 | |||||
程序注意了哪些规范 | 代码格式、常量的定义、函数的声明 | |||||
你进行了哪些测试 | — | |||||
程序进行了哪些有效性检查 | — | |||||
你是如何保证程序的高效率的 | — |
相关文章推荐
- 用多线程实现“生产者-消费者问题”(代码+实验报告)
- java代码实现多线程消费者生产者问题。
- C++ 11新特性之用多线程实现生产者消费者问题
- Java 多线程实现生产者消费者问题(wait/notify)
- 利用条件变量实现多线程生产者消费者问题
- linux下多线程互斥量实现生产者--消费者问题和哲学家就餐问题
- 生产者消费者问题(附代码)& 多线程 线程池
- java多线程实现生产者与消费者问题
- Linux下用条件变量实现多线程间生产者与消费者问题
- 用JAVA实现多线程(生产者与消费者问题)
- JAVA多线程实现生产者消费者问题
- java多线程总结六:经典生产者消费者问题实现
- 多线程_生产者消费者问题代码1
- 关于网宿厦门研发中心笔试的一道PV操作题:利用java中的多线程实现生产者与消费者的同步问题
- Ruby中用线程实现经典的生产者消费者问题代码实例
- 生产者消费者问题 伪代码和C语言多线程实现
- 多线程经典问题之生产者消费者问题的JAVA实现
- Java多线程实现生产者消费者延伸问题
- 多线程(线程间通信-多生产者多消费者问题-JDK1.5解决办法-范例),停止线程,线程中方法的区别,匿名内部类实现多线程,线程总结
- 用BlockBoundQueue和c++11实现多线程生产者消费者问题