VC++学习:用vc实现生产者消费者问题

合集下载

操作系统实验三 生产者——消费者问题

操作系统实验三 生产者——消费者问题

操作系统实验三:生产者——消费者问题一、基本信息xxx 711103xx 2012年4月29日二、实验目的通过实验,掌握Windows和Linux环境下互斥锁和信号量的实现方法,加深对临界区问题和进程同步机制的理解,同时巩固利用Windows API和Pthread API进行多线程编程的方法。

三、实验内容1. 在Windows操作系统上,利用Win32 API提供的信号量机制,编写应用程序实现生产者——消费者问题。

2. 在Linux操作系统上,利用Pthread API提供的信号量机制,编写应用程序实现生产者——消费者问题。

3. 两种环境下,生产者和消费者均作为独立线程,并通过empty、full、mutex 三个信号量实现对缓冲进行插入与删除。

4. 通过打印缓冲区中的内容至屏幕,来验证应用程序的正确性。

四、实验步骤1. 创建3个信号量:Mutex、Full、Empty2. 主程序创建10个生产者线程和10个消费者线程,之后休眠一段时间3. 生产者线程中,休息一段2s后,生产一个0~10的随机数放入缓冲区里。

利用信号量Mutex产生对缓冲区使用的互斥功能,利用Empty和Full信号量来对缓冲区进行增加项4. 消费者线程中,休息4s时间后,消费一个缓冲区的数据。

利用信号量Mutex产生对缓冲区使用的互斥功能,利用Empty和Full信号量来对缓冲区进行增加项5. 主程序执行一段时间后,结束整个程序五、主要数据结构及其说明产品数量最大值const int MAX_SIZE = 10;缓冲区:int buffer[BUFFER_SIZE];int front; int rear; bool full;三个互斥信号量:HANDLE Mutex; HANDLE Full; HANDLE Empty;有关操作:用WaitForSingleSignal函数可以获得一个Mutex的所有权,类似于P 操作,而ReleaseMutex函数可以释放一个Mutex的所有权,类似于V 操作。

生产者消费者问题模拟实现(z)

生产者消费者问题模拟实现(z)

int *pcq; //信号量队列指针
} Seamphore;
int producerCongestionQueue[processNum]; //等待信号量 empty
的阻塞队列 int consumerCongestionQueue[processNum]; //等待信
号量 full 的阻塞队列
用信号量机制解决生产者—消费者问题可描述如下:
item B[k];
semaphore empty; empty=k; //可以使用的空缓冲区数
semaphore full; full=0;
//缓冲区内可以使用的产品数
semaphore mutex; mutex=1; //互斥信号量
int in=0; //放入缓冲区指针
号量 s 的阻塞队列中。
(2)V(s):s.value++;若 s.value≤0,则执行 V(s)的进程从等待
信号量 s 的阻塞队列中唤醒头一个进程,然后自己继续执行。若
s.value>0 ,则执行 V(s)
的进程继续执行;
1.2.3 信号量实现互斥
信号量和 PV 操作可用来解决进程互斥问题。为使多个进程能互斥地
append to B[in];
out =
(out+1)%k;
in = (in+1)%k;
V(mutex);
V(mutex);
V(empty);
V(full);
consume();
}
}}
}
Coend
程序中的 P(mutex)和 V(mutex)必须成对出现,夹在两者之间的代码
段是临界区;施加于信号量 empty 和 full 上的 PV 操作也必须成对出

操作系统课程设计生产者-消费者问题附代码

操作系统课程设计生产者-消费者问题附代码

枣庄学院信息科学与工程学院课程设计任务书题目:生产者-消费者问题的实现姓名:学号:专业:计算机科学与技术课程:操作系统指导教师:刘彩霞职称:讲师完成时间:2012年5月----2012 年6月枣庄学院信息科学与工程学院制课程设计任务书及成绩评定目录第1章引言 (1)1.1 设计背景 (1)1.2 问题分类 (1)1.3 解决方案 (1)第2章设计思路及原理 (2)第3章程序详细设计 (3)3.1程序模块设计 (3)3.2程序代码结构 (5)第4章实验结果 (7)第5章实验总结 (8)附录:实验代码 (9)第1章引言1.1 设计背景生产者-消费者问题是一个经典的进程同步问题,该问题最早由Dijkstra 提出,用以演示他提出的信号量机制。

在同一个进程地址空间内执行的两个线程。

生产者线程生产物品,然后将物品放置在一个空缓冲区中供消费者线程消费。

消费者线程从缓冲区中获得物品,然后释放缓冲区。

当生产者线程生产物品时,如果没有空缓冲区可用,那么生产者线程必须等待消费者线程释放出一个空缓冲区。

当消费者线程消费物品时,如果没有满的缓冲区,那么消费者线程将被阻塞,直到新的物品被生产出来。

1.2 问题分类根据缓冲区的个数、大小以及生产者消费者的个数可以分为以下几类:1.单缓冲区(适合单或多生产消费者);2.环行多缓冲区(或无穷缓冲区)单生产消费者;3.环行多缓冲区多生产消费者;1.3 解决方案1.用进程通信(信箱通信)的方法解决;2.进程消息缓冲通信;3.进程信箱通信;第2章设计思路及原理设计了两个主要函数:生产者函数、消费者函数;设计了三个信号量:full信号量,判断缓冲区是否有值,初值为0;empty信号量,判断缓冲区是否有空缓冲区,初值为缓冲区数;mutex信号量作为互斥信号量,用于互斥的访问缓冲区。

生产者函数通过执行P操作信号量empty减1,判断缓冲区是否有空。

有空则互斥的访问缓冲区并放入数据,然后释放缓冲区,执行V操作,信号量full 加1。

操作系统实验参考代码

操作系统实验参考代码

目录实验一WINDOWS进程初识 (2)实验二进程管理 (6)实验三进程同步的经典算法 (10)实验四存储管理 (14)试验五文件系统试验 (18)实验有关(参考)代码实验一WINDOWS进程初识1、实验目的(1)学会使用VC编写基本的Win32 Consol Application(控制台应用程序)。

(2)掌握WINDOWS API的使用方法。

(3)编写测试程序,理解用户态运行和核心态运行。

2、程序清单清单1-1 一个简单的Windows控制台应用程序// hello项目# include <iostream>void main(){std::cout << “Hello, Win32 Consol Application” << std :: endl ;}清单1-2 核心态运行和用户态运行时间比计算// proclist项目# include <windows.h># include <tlhelp32.h># include <iostream.h>// 当在用户模式机内核模式下都提供所耗时间时,在内核模式下进行所耗时间的64位计算的帮助方法DWORD GetKernelModePercentage(const FILETIME& ftKernel,const FILETIME& ftUser){// 将FILETIME结构转化为64位整数ULONGLONG qwKernel=(((ULONGLONG)ftKernel.dwHighDateTime)<<32)+ftKernel.dwLowDateTime;ULONGLONG qwUser=(((ULONGLONG)ftUser.dwHighDateTime)<<32)+ftUser.dwLowDateTime;// 将消耗时间相加,然后计算消耗在内核模式下的时间百分比ULONGLONG qwTotal=qwKernel+qwUser;DWORD dwPct=(DWORD)(((ULONGLONG)100*qwKernel)/qwTotal);return(dwPct);}// 以下是将当前运行过程名和消耗在内核模式下的时间百分数都显示出来的应用程序void main(int argc,char *argv[]){if(argc<2){cout<<"请给出你要查询的程序名"<<endl;exit(0);}// 对当前系统中运行的过程拍取“快照”HANDLE hSnapshot=::CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,// 提取当前过程0);// 如果是当前过程,就将其忽略// 初始化过程入口PROCESSENTRY32 pe;::ZeroMemory(&pe,sizeof(pe));pe.dwSize=sizeof(pe);BOOL bMore=::Process32First(hSnapshot,&pe);BOOL found = FALSE;while(bMore){// 打开用于读取的过程if(!strcmp(pe.szExeFile,argv[1])){found = TRUE;HANDLE hProcess=::OpenProcess(PROCESS_QUERY_INFORMA TION,// 指明要得到信息FALSE,// 不必继承这一句柄pe.th32ProcessID);// 要打开的进程if (hProcess!=NULL){// 找出进程的时间FILETIME ftCreation,ftKernelMode,ftUserMode,ftExit;::GetProcessTimes(hProcess,// 所感兴趣的进程&ftCreation,// 进程的启动时间&ftExit,// 结束时间(如果有的话)&ftKernelMode,// 在内核模式下消耗的时间&ftUserMode);// 在用户模式下消耗的时间// 计算内核模式消耗的时间百分比DWORD dwPctKernel=::GetKernelModePercentage(ftKernelMode,// 在内核模式上消耗的时间ftUserMode);// 在用户模式下消耗的时间// 向用户显示进程的某些信息cout<< "process ID: " << pe.th32ProcessID<< ",EXE file:" << pe.szExeFile<< ",%d in Kernel mode: " << dwPctKernel << endl;// 消除句柄::CloseHandle(hProcess);}}// 转向下一个进程bMore=::Process32Next(hSnapshot,&pe);}if(found==FALSE){cout<<"当前系统没有这个可执行程序正在运行"<<endl;exit(0);}}清单1-3 核心态运行和用户态运行时间测试程序#include <stdio.h>main(){int i,j;while(1){for(i=0;i<1000;i++);for(j=1;j<1000;j++) printf(“enter kernel mode running.”);}}实验二进程管理1、实验目的1) 通过创建进程、观察正在运行的进程和终止进程的程序设计和调试操作,进一步熟悉操作系统的进程概念,理解Windows进程的“一生”。

生产者消费者问题实验报告

生产者消费者问题实验报告

操作系统课程设计实验报告实验名称: 生产者消费者问题姓名/学号:一、实验目的以生产者和消费者问题为例, 学习Linux和Windows下进程通信、同步机制的具体实现方法, 主要是信号量和共享内存。

熟悉相关系统API的用法。

二、实验内容使用共享内存和信号量机制来实现多个生产者/消费者进程间的通信和同步。

要求在Linux和Windows下分别实现。

缓冲区大小为3, 初始为空。

2个生产者, 随机等待一段时间, 往缓冲区添加数据, 重复6次。

3个消费者, 重复4次。

三、实验环境Ubuntu 10.10 , GCC; Windows 7, VC 6.0;四、程序设计与实现1.Linux下:(1) 数据结构:a.共享内存定义为一个结构, 使得其数据成员更清晰且操作变得简单。

b.共享缓冲区采用循环队列的数据结构,由上面的结构struct buf { int start; int end; int info[BUF_NUM]; }维护。

其中start为队头指针, end为队尾指针, info为数据区域。

(2) 算法:a.大致由三个模块组成:i.主程序(main):ii.创建信号量、共享内存并进行初始化iii.创建生产者、消费者进程, 生产者执行pro_fun(), 消费者执行con_fun()iv.等待所有子进程的结束v.删除信号量、共享内存i.生产者进程(pro_fun):ii.通过key获得信号量、共享内存的ID, 将内存添加到自己的地址空间iii.P(empty), P(mutex), Add(data), V(mutex), V(full)iv.解除和共享内存的关联i.消费者进程(con_fun):ii.通过key获得信号量、共享内存的ID, 将内存添加到自己的地址空间iii.P(full), P(mutex), Add(data), V(mutex), V(empty)iv.解除和共享内存的关联循环队列部分:加入数据: info[end] = value; end = (end + 1) % 3;取出数据: temp = info[start]; info[start] = 0; (start = start + 1)%3; return temp;(3) 程序流程图:a.主函数:b.生产者进程:c.消费者进程和生产者类似4.Windows 下:(1) 数据结构:和Linux大致相同(2) 算法:a.创建的子进程调用正在执行的文件本身, 通过main函数的参数区分主进程和生产者、消费者进程。

(完整word版)生产者-消费者问题

(完整word版)生产者-消费者问题

课程设计报告课程名:操作系统专业学生姓名班级学号指导教师完成日期博雅学院“操作系统”课程设计报告-—生产者—消费者问题的模拟实现1.课程设计的目的本课程设计是学习完“操作系统原理”课程后进行的一次全面的综合训练,通过课程设计,更好地掌握操作系统的原理及实现方法,加深对操作系统基础理论和重要算法的理解,加强学生的动手能力。

2.设计内容2.1 概述用多进程同步方法解决生产者-消费者问题,C或C++语言实现。

通过研究Linux 的进程机制和信号量实现生产者消费者问题的并发控制。

说明:有界缓冲区内设有20个存储单元,放入/取出的数据项设定为1-20这20个整型数.设计要求:(1)每个生产者和消费者对有界缓冲区进行操作后,即时显示有界缓冲区的全部内容,当前指针位置和生产者/消费者县城的标识符。

(2)生产者和消费者各有两个以上。

(3)多个生产者或多个消费者之间须有共享对缓冲区进行操作的函数代码。

2.2 设计原理多进程是一种非常简洁的多任务操作方式。

在Linux系统下,启动一个新的进程必须分配给它独立的地址空间,建立众多的数据表来维护它的代码段、堆栈段和数据段,这是一种烦琐的多任务工作方式。

生产者-消费者方案是多进程应用程序开发中最常用的构造之一。

因此困难也在于此。

因为在一个应用程序中可以多次重复生产者—消费者行为,其代码也可以如此。

设计中创建了Consumer 类,该类通过在一些多进程应用程序中促进代码重用以及简化代码调试和维护来解决这个问题。

多进程应用程序通常利用生产者—消费者编程方案,其中由生产者进程创建重复性作业,将其传递给作业队列,然后由消费者进程处理作业.多进程是一种使应用程序能同时处理多个操作的编程技术。

通常有两种不同类型的多进程操作使用多个进程:适时事件,当作业必须在特定的时间或在特定的间隔内调度执行时;后台处理,当后台事件必须与当前执行流并行处理或执行时;适时事件的示例包括程序提醒、超时事件以及诸如轮询和刷新之类的重复性操作。

生产者与消费者问题(附源码)

生产者与消费者问题(附源码)

操作系统实验报告专业网络工程班级08102 学号姓名课程名称操作系统学年2010-2011 学期下课程类别专业必修■限选□任选□实践□实验时间2010年11月3日实验名称实验一:生产者与消费者问题实验目的和要求全面理解生产者与消费者问题模型,掌握解决该问题的算法思想,正确使用同步机制。

实验软硬件要求Pentium ||| 450以上CPU 64MB以上内存WINDOWS XPVisual C++6.0实验内容、方法和步骤(可附页)问题描述:一组生产者向一组消费者提供商品,共享一个有界缓冲池,生产者向其中放入商品,消费者从中取得商品。

假定这些生产者和消费者互相等效,只要缓冲池未满,生产者可将商品送入缓冲池;只要缓冲池未空,消费者可从缓冲池取走一商品。

功能要求:根据进程同步机制,编写一个解决上述问题的程序,可显示缓冲池状态、放商品、取商品等过程。

具体参数:3个生产者进程,2个消费者进程;缓冲区单元个数N=4;在本程序中是缓冲区中的数从0变为1表示模拟生产一个产品,消费时则将对应缓冲区内的1变为0,为模拟消费一个产品。

实验结果(可附页)见截图小结这次多线程的操作系统实验,使我对线程的概念以及多线程程序中线程间的运行有了更深的认识,同时也让我的编程能力得到了一定的提高。

这次做的用多线程实现生产者与消费者模型的实验,由于我的编程能力基础比较差,对线程也是一无所知,所以一开始觉得无从下手,但幸好老师给了充足的时间,我通过看网上找的视频资料以及请教同学才渐渐地有了一点概念,然后我试着从网上下了一些多线程的程序分析里面的语句,基本弄懂了多线程的原理。

评定成绩:批阅教师:年月日一、问题概述三个生产者向两个消费者提供消息,它们共享一个有界缓冲池,缓冲池有四个缓冲区,生产者向其中投放消息,消费者从中取得消息。

假定这些生产者和消费者互相等效,只要缓冲池未满,生产者可将消息送入缓冲池;只要缓冲池未空,消费者可从缓冲池取走一个消息。

生产者消费者pv例题

生产者消费者pv例题

生产者消费者pv例题生产者消费者问题是一个经典的并发编程问题,主要涉及到多个线程之间的同步和通信。

这个问题可以分为两部分:生产者和消费者。

生产者负责生成一定量的数据放到缓冲区,而消费者则从缓冲区中取出数据。

为了防止缓冲区溢出和被耗尽,需要使用到信号量等机制来进行同步。

以下是一个简单的生产者消费者问题的例子,用到了PV操作来控制:```c#include <stdio.h>#include <pthread.h>#include <stdlib.h>#define BUFFER_SIZE 100int buffer[BUFFER_SIZE];int in = 0, out = 0;pthread_mutex_t mutex; //互斥锁pthread_cond_t cond_empty, cond_full; //条件变量,分别表示缓冲区空和缓冲区满void *producer(void *arg) {int item;while (1) {item = produce_item(); //生产数据pthread_mutex_lock(&mutex);while ((in + 1) % BUFFER_SIZE == out) { //缓冲区满,等待消费者消费pthread_cond_wait(&cond_empty, &mutex);}buffer[in] = item;in = (in + 1) % BUFFER_SIZE; //入队printf("Producer produced item: %d\n", item);pthread_cond_signal(&cond_full); //唤醒消费者线程,告诉缓冲区有新数据可消费pthread_mutex_unlock(&mutex);}}void *consumer(void *arg) {while (1) {pthread_mutex_lock(&mutex);while (in == out) { //缓冲区空,等待生产者生产数据pthread_cond_wait(&cond_full, &mutex);}int item = buffer[out];out = (out + 1) % BUFFER_SIZE; //出队printf("Consumer consumed item: %d\n", item);pthread_cond_signal(&cond_empty); //唤醒生产者线程,告诉缓冲区有空间可放新数据pthread_mutex_unlock(&mutex);}}```。

操作系统实验报告三大问题之生产者与消费者问题

操作系统实验报告三大问题之生产者与消费者问题

计算机操作系统实验报告题目三大经典问题之生产者与消费者问题一、课程设计的性质与任务1、加深对并发协作进程同步与互斥概念的理解。

通过编写程序实现进程同步和互斥,使学生掌握有关进程(线程)同步与互斥的原理,以及解决进程(线程)同步和互斥的算法,从而进一步巩固进程(线程)同步和互斥等有关的内容。

2、掌握进程和线程的概念,进程(线程)的控制原语或系统调用的使用。

3、了解Windows2000/XP中多线程的并发执行机制,线程间的同步和互斥。

学习使用Windows2000/XP中基本的同步对象,掌握相应的API函数。

4、培养学生能够独立进行知识综合,独立开发较大程序的能力。

5、培养提高学生软件开发能力和软件的调试技术。

6、培养学生开发大型程序的方法和相互合作的精神。

7、培养学生的创新意识。

8、培养学生的算法设计和算法分析能力。

9、培养学生对问题进行文字论述和文字表达的能力。

二、课程设计的内容及其要求在Windows?XP、Windows?2000等操作系统下,使用的VC、VB、Java或C等编程语言,采用进程(线程)同步和互斥的技术编写程序实现生产者消费者问题或哲学家进餐问题或读者-写者问题或自己设计一个简单进程(线程)同步和互斥的实际问题。

要求:(1)经调试后程序能够正常运行。

(2)采用多进程或多线程方式运行,体现了进程(线程)同步互斥的关系。

(3)程序界面美观。

三、实验原理本实验要求利用PV操作实现解决生产者——消费者问题中的同步问题。

此问题描述的是一群生产者进程在生产产品并将这些产品提供给消费者进程去消费,在两者之间设置了一个具有n个缓冲区的缓冲池,生产者进程将它所生产的产品放入一个缓冲区,消费者进程可从缓冲区中取走产品去消费,但它们之间必须保持同步,即不允许消费者进程到一个空缓冲区去取产品,也不允许生产者进程向一个已装满且尚未取出的缓冲区中投放产品,并且生产者消费者互斥使用缓冲区。

四、实验原理图五、算法实现(1)有一个生产者线程ProduceThread,有1个消费者进程CustomerThread;缓冲区为shareList。

C语言编程模拟生产者和消费者问题(附代码程序)

C语言编程模拟生产者和消费者问题(附代码程序)

C语言编程模拟生产者和消费者问题(附代码程序)实验三编程模拟生产者和消费者问题一、实验目的和要求模拟实现用同步机构避免发生进程执行时可能出现的与时间有关的错误。

进程是程序在一个数据集合上运行的过程,进程是并发执行的,也即系统中的多个进程轮流地占用处理器运行。

我们把若干个进程都能进行访问和修改的那些变量称为公共变量。

由于进程是并发地执行的,所以,如果对进程访问公共变量不加限制,那么就会产生“与时间有关”的错误,即进程执行后所得到的结果与访问公共变量的时间有关。

为了防止这类错误,系统必须要用同步机构来控制进程对公共变量的访问。

一般说,同步机构是由若干条原语一一同步原语一一所组成。

本实习要求学生模拟PV操作同步机构的实现,模拟进程的并发执行,了解进程并发执行时同步机构的作用。

二、实验环境Windows操作系统和VisualC++6.0专业版或企业版三、实验步骤模拟PV操作同步机构,且用PV操作解决生产者一一消费者问题。

[提示]:⑴PV操作同步机构,由P操作原语和V操作原语组成,它们的定义如下:P操作原语P(s):将信号量s减去1,若结果小于0,则执行原语的进程被置成等待信号量s的状态。

V操作原语V(s):将信号量s加1,若结果不大于0,则释放一个等待信号量s的进程。

这两条原语是如下的两个过程:procedurep(vars:semaphore);begi ns:=s-1;ifs<0the nW(s)en d{p}procedurev(vars:semaphore);egin s:=s+1;ifs _Othe nR(s)en d{v}其中W (s)表示将调用过程的进程置为等待信号量s的状态;R (s)表示释放一个等待信号量s的进程。

在系统初始化时应把semaphore定义为某个类型,为简单起见,在模拟实习中可把上述的semaphore直接改成integer。

(2) 生产者一一消费者问题。

假定有一个生产者和一个消费者,生产者每次生产一件产品,并把生产的产品存入共享缓冲器以供消费者取走使用。

设计模式之生产者和消费者

设计模式之生产者和消费者

设计模式之⽣产者和消费者⼀.简介⽣产者消费者模式并不是GOF提出的23种设计模式之⼀,23种设计模式都是建⽴在⾯向对象的基础之上的,但其实⾯向过程的编程中也有很多⾼效的编程模式,⽣产者消费者模式便是其中之⼀,它是我们编程过程中最常⽤的⼀种设计模式。

在实际的软件开发过程中,经常会碰到如下场景:某个模块负责产⽣数据,这些数据由另⼀个模块来负责处理(此处的模块是⼴义的,可以是类、函数、线程、进程等)。

产⽣数据的模块,就形象地称为⽣产者;⽽处理数据的模块,就称为消费者。

单单抽象出⽣产者和消费者,还够不上是⽣产者/消费者模式。

该模式还需要有⼀个缓冲区处于⽣产者和消费者之间,作为⼀个中介。

⽣产者把数据放⼊缓冲区,⽽消费者从缓冲区取出数据。

⼤概的结构如下图。

为了不⾄于太抽象,我们举⼀个寄信的例⼦(虽说这年头寄信已经不时兴,但这个例⼦还是⽐较贴切的)。

假设你要寄⼀封平信,⼤致过程如下:你把信写好——相当于⽣产者制造数据你把信放⼊邮筒——相当于⽣产者把数据放⼊缓冲区邮递员把信从邮筒取出——相当于消费者把数据取出缓冲区邮递员把信拿去邮局做相应的处理——相当于消费者处理数据⼆.优点解耦假设⽣产者和消费者分别是两个类。

如果让⽣产者直接调⽤消费者的某个⽅法,那么⽣产者对于消费者就会产⽣依赖(也就是耦合)。

将来如果消费者的代码发⽣变化,可能会影响到⽣产者。

⽽如果两者都依赖于某个缓冲区,两者之间不直接依赖,耦合也就相应降低了。

接着上述的例⼦,如果不使⽤邮筒(也就是缓冲区),你必须得把信直接交给邮递员。

有同学会说,直接给邮递员不是挺简单的嘛?其实不简单,你必须得认识谁是邮递员,才能把信给他(光凭⾝上穿的制服,万⼀有⼈假冒,就惨了)。

这就产⽣和你和邮递员之间的依赖(相当于⽣产者和消费者的强耦合)。

万⼀哪天邮递员换⼈了,你还要重新认识⼀下(相当于消费者变化导致修改⽣产者代码)。

⽽邮筒相对来说⽐较固定,你依赖它的成本就⽐较低(相当于和缓冲区之间的弱耦合)。

生产者消费者实验报告

生产者消费者实验报告

生产者消费者实验报告实验二.生产者与消费者进程实验报告实验目的:利用Windows提供的API函数,编写程序,解决生产者与消费者问题,实现进程的互斥与同步。

实验内容与步骤:1.进程的互斥与同步。

编写一段程序,模拟生产者和消费者线程,实现进程的互斥与同步。

2.利用VC++6.0实现上述程序设计和调试操作,对于生产者和消费者线程操作的成功与否提供一定的提示框。

3.通过阅读和分析实验程序,熟悉进程的互斥与同步的概念。

程序设计思路:关于这个生产者与消费者进程,我主要设计了两个线程,一个生产者线程,一个消费者线程。

整个进程随着这两个线程的创建,运行,终止而进行。

在程序的开始,首先我创建了一个结构struct,它包括的基本数据有:生产物品缓冲区(用队列来表示),一个标志缓冲区空间多少的信号量m_S_Empty,一个标志缓冲区已有物品多少的信号量m_S_Full,一个互斥信号量m_M_Mutex 防止生产者与消费者同时访问缓冲区间,一个判断生产者是否要结束生产的bool类型标志producerfinished,若为true,则两个线程都终止。

进入主程序以后,首先对这些struct中的基本数据进行一个个赋值,然后创建生产者与消费者两个线程,等待两个线程都结束时,关闭进程。

要知道在main主函数中两个线程的创建语句就是对两个线程各自进入函数的运行,生产者函数中通过一个for循环,可以控制生产者进行多次生产,不是生产一次就结束了。

消费者函数中通过一个while循环,当生产者没有结束生产时可以控制消费者进行多次消费,不是消费一次就不会再来消费了,除非生产者已结束生产,即producerfinished的值变为true。

实验主要程序及注释:#include"stdafx.h"#include<windows.h>#include<iostream>#include<queue>#include<process.h>using namespace std;DWORD WINAPI Consumer(void*);//声明消费者函数DWORD WINAPI Producer(void*);//声明生产者函数#define N 10//定义缓冲区数量/*数据结构的定义*/struct MyData{HANDLE m_S_Empty;// 生产者SemaphoreHANDLE m_S_Full; // 消费者SemaphoreHANDLE m_M_Mutex;//互斥信号量queue<int> food; //定义共享缓冲区bool producerfinished;//标志着生产者是否结束生产};int j=0;//只是为了输出方便观察线程执行次数int main(){ /*对各个信号量赋值*/MyData mydata;//创建一个MyData数据类型的实体mydatamydata.m_M_Mutex = CreateMutex(NULL, false, NULL);//"false"表示刚刚创建的这个信号量不属于®¨²任何线程mydata.m_S_Empty = CreateSemaphore(NULL, N, N, NULL);//初始计数为Nmydata.m_S_Full = CreateSemaphore(NULL, 0, N, NULL);//初始计数为0mydata.producerfinished=false;//生产者结束标志刚开始设置为false,表示没有结束/*创建生产者和消费者线程*/HANDLE handles[2];handles[0] = CreateThread(NULL,0,&Producer,(void*)&mydata,0,0);handles[1] = CreateThread(NULL,0,&Consumer,(void*)&mydata,0,0);WaitForMultipleObjects(2, handles, true, INFINITE); //等待两个线程都结束才往下执行 CloseHandle(mydata.m_M_Mutex);CloseHandle(mydata.m_S_Full);CloseHandle(mydata.m_S_Empty);}/*生产者函数*/DWORD WINAPI Producer(void* lp){MyData * md = (MyData*)lp;for(int i =0 ; i < 100; i++){WaitForSingleObject(md->m_S_Empty, INFINITE);//缓冲区有空间才可以往下WaitForSingleObject(md->m_M_Mutex, INFINITE);//消费者没有在操作缓冲区生产者才可以执行/*将所生产的物品放到指定的缓冲区中*/md->food.push(1);printf("%d\t生产1个物品,共有%d个物品\t\t%d\n",j++,md->food.size(),GetCurrentThreadId());//输出缓冲区信息以及线程信息ReleaseMutex(md->m_M_Mutex);//释放互斥信号量ReleaseSemaphore(md->m_S_Full, 1, NULL);//有物品的缓冲区增加一个}md->producerfinished=true;//若出了for循环,生产者结束生产,控制消费者线程结束return 0;}/*消费者函数*/DWORD WINAPI Consumer(void* lp){MyData * md = (MyData*)lp;while(!md->producerfinished){//若生产者没有结束生产,可以继续往下执行WaitForSingleObject(md->m_S_Full,INFINITE);//若缓冲区没有空,则可以往下执行WaitForSingleObject(md->m_M_Mutex,INFINITE);//若生产者没有在操作缓冲区,则消费则可以操作/*消费一个物品*/md->food.pop();printf("%d\t消费1个物品,共有%d个物品\t\t%d\n",j++,md->food.size(),GetCurrentThreadId());//输出缓冲区信息以及线程信息ReleaseMutex(md->m_M_Mutex); //释放互斥信号量ReleaseSemaphore(md->m_S_Empty,1,NULL);//空缓冲区增加一个}return 0;}实验中遇到的问题及解决:我的这个程序是结合了老师ppt上给的程序框架,然后理解了精品课程上给的程序自己重新整理写的。

生产者消费者问题

生产者消费者问题
down(&mutex); // 进入临界区
insert_item(item); // 将新数据放入缓冲区
up(&mutex); // 离开临界区
if (count == N -1) // 缓冲区有空槽
{ // 唤醒生产者
consumer_item(item); // 处理数据项
}
}
该解决方案使用了三个信号量:一个为 full,用来记录充满的缓冲槽的数目,一个为 empty,记录空的缓冲槽总数,一个为 mutex,用来确保生产者和消费者不会同时访问缓冲区。mutex 的初始值为 1,供两个或者多个进程使用的信号量,保证同一个时刻只有一个进程可以进入临界区,称为二元信号量(binary semaphore)。如果每一个进程在进入临界区前都执行一个 down(...),在刚刚退出临界区时执行一个 up(...),就能够实现互斥。
生产者-消费者(producer-consumer)问题,也称作有界缓冲区(bounded-buffer)问题,两个进程共享一个公共的固定大小的缓冲区。其中一个是生产者,用于将消息放入缓冲区;另外一个是消费者,用于从缓冲区中取出消息。问题出现在当缓冲区已经满了,而此时生产者还想向其中放入一个新的数据项的情形,其解决方法是让生产者此时进行休眠,等待消费者从缓冲区中取走了一个或者多个数据后再去唤醒它。同样地,当缓冲区已经空了,而消费者还想去取消息,此时也可以让消费者进行休眠,等待生产者放入一个或者多个数据时再唤醒它。
// 缓冲区大小
#define N 100
int count = 0; // 跟踪缓冲区的记录数
/* 生产者进程 */
void procedure(void)

操作系统之进程(生产者---消费者)实验报告

操作系统之进程(生产者---消费者)实验报告

操作系统实验报告——生产者和消费者问题姓名:学号:班级:一、实验内容1、模拟操作系统中进程同步和互斥;2、实现生产者和消费者问题的算法实现;二、实验目的1、熟悉临界资源、信号量及PV操作的定义与物理意义;2、了解进程通信的方法;3、掌握进程互斥与进程同步的相关知识;4、掌握用信号量机制解决进程之间的同步与互斥问题;5、实现生产者-消费者问题,深刻理解进程同步问题;三、实验题目在Windows操作系统下用C语言实现经典同步问题:生产者—消费者,具体要求如下:(1)一个大小为10的缓冲区,初始状态为空。

(2)2个生产者,随机等待一段时间,往缓冲区中添加数据,若缓冲区已满,等待消费者取走数据之后再添加,重复10次。

页脚内容1(3)2个消费者,随机等待一段时间,从缓冲区中读取数据,若缓冲区为空,等待生产者添加数据之后再读取,重复10次。

四、思想本实验的主要目的是模拟操作系统中进程同步和互斥。

在系统进程并发执行异步推进的过程中,由于资源共享和进程间合作而造成进程间相互制约。

进程间的相互制约有两种不同的方式。

(1)间接制约。

这是由于多个进程共享同一资源(如CPU、共享输入/输出设备)而引起的,即共享资源的多个进程因系统协调使用资源而相互制约。

(2)直接制约。

只是由于进程合作中各个进程为完成同一任务而造成的,即并发进程各自的执行结果互为对方的执行条件,从而限制各个进程的执行速度。

生产者和消费者是经典的进程同步问题,在这个问题中,生产者不断的向缓冲区中写入数据,而消费者则从缓冲区中读取数据。

生产者进程和消费者对缓冲区的操作是互斥,即当前只能有一个进程对这个缓冲区进行操作,生产者进入操作缓冲区之前,先要看缓冲区是否已满,如果缓冲区已满,则它必须等待消费者进程将数据取出才能写入数据,同样的,消费者进程从缓冲区读取数据之前,也要判断缓冲区是否为空,如果为空,则必须等待生产者进程写入数据才能读取数据。

在本实验中,进程之间要进行通信来操作同一缓冲区。

生产者消费者问题/银行家算法

生产者消费者问题/银行家算法

操作系统课程设计题目一:实现生产者消费者问题题目二:银行家算法的实现一、实验题目解决生产者-消费者问题二、设计内容有界缓冲区内设有10个存储单元,放入/取出的数据项设定为1~10这10个整形数。

要求每个生产者和消费者对有界缓冲区进行操作后,即时显示有界缓冲区的全部内容、当前指针位置和生产者/消费者标识符三、开发环境LINUX环境,工具为VI编辑器。

四、分析设计(一)实验原理使用的生产者和消费者模型具有如下特点:(1)本实验的多个缓冲区不是环形循环的,也不要求按顺序访问。

生产者可以把产品放到目前某一个空缓冲区中。

(2)消费者只消费指定生产者的产品。

(3)在测试用例文件中指定了所有的生产和消费的需求,只有当共享缓冲区的数据满足了所有关于它的消费需求后,此共享缓冲区才可以作为空闲空间允许新的生产者使用。

(4)本实验在为生产者分配缓冲区时各生产者间必须互斥,此后各个生产者的具体生产活动可以并发。

而消费者之间只有在对同一产品进行消费时才需要互斥,同时它们在消费过程结束时需要判断该消费对象是否已经消费完毕并清除该产品。

Windows 用来实现同步和互斥的实体。

在Windows 中,常见的同步对象有:信号量(Semaphore)、互斥量(Mutex)、临界段(CriticalSection)和事件(Event)等。

本程序中用到了前三个。

使用这些对象都分为三个步骤,一是创建或者初始化:接着请求该同步对象,随即进入临界区,这一步对应于互斥量的上锁;最后释放该同步对象,这对应于互斥量的解锁。

这些同步对象在一个线程中创建,在其他线程中都可以使用,从而实现同步互斥。

当然,在进程间使用这些同步对象实现同步的方法是类似的。

1.用锁操作原语实现互斥为解决进程互斥进人临界区的问题,可为每类临界区设置一把锁,该锁有打开和关闭两种状态,进程执行临界区程序的操作按下列步骤进行:①关锁。

先检查锁的状态,如为关闭状态,则等待其打开;如已打开了,则将其关闭,继续执行步骤②的操作。

生产者消费者问题总结

生产者消费者问题总结

⽣产者消费者问题总结⽣产者-消费者算是并发编程中常见的问题。

依靠缓冲区我们可以实现⽣产者与消费者之间的解耦。

⽣产者只管往缓冲区⾥⾯放东西,消费者只管往缓冲区⾥⾯拿东西。

这样我们避免⽣产者想要交付数据给消费者,但消费者此时还⽆法接受数据这样的情况发⽣。

wait notify这个问题其实就是线程间的通讯,所以要注意的是不能同时读写。

⽣产者在缓冲区满的时候不⽣产,等待;消费者在缓冲区为空的时候不消费,等待。

⽐较经典的做法是wait和notify。

⽣产者线程执⾏15次set操作public class Producer implements Runnable{private Channel channel;public Producer(Channel channel) {this.channel = channel;}@Overridepublic void run() {for(int i=0;i<15;i++){channel.set(Thread.currentThread().getName()+" "+i);}}}消费者线程执⾏10次get操作public class Consumer implements Runnable {private Channel channel;public Consumer(Channel channel) {this.channel = channel;}@Overridepublic void run() {for(int i=0;i<10;i++){System.out.println("Consumer "+Thread.currentThread().getName()+" get "+channel.get());}}}现在定义Channel类,并创建两个⽣产者线程和三个消费者线程public class Channel {private List<String> buffer=new ArrayList<>();private final int MAX_SIZE=10;public synchronized String get(){while (buffer.size()==0){//不要⽤if,醒来了也要再次判断try {wait();} catch (InterruptedException e) {e.printStackTrace();}}String str=buffer.remove(0);notifyAll();return str;}public synchronized void set(String str){while (buffer.size()==MAX_SIZE){try {wait();} catch (InterruptedException e) {e.printStackTrace();}}buffer.add(str);notifyAll();}public static void main(String[] args) {Channel channel=new Channel();Producer producer=new Producer(channel);Consumer consumer=new Consumer(channel);for(int i=0;i<2;i++){new Thread(producer).start();}for (int i=0;i<3;i++){new Thread(consumer).start();}}}使⽤notifyAll⽽不是notify的原因是,notify有可能出现多次唤醒同类的情况,造成“假死”。

操作系统实验报告经典生产者—消费者问题范文大全[修改版]

操作系统实验报告经典生产者—消费者问题范文大全[修改版]

第一篇:操作系统实验报告经典生产者—消费者问题实验二经典的生产者—消费者问题一、目的实现对经典的生产者—消费者问题的模拟,以便更好的理解经典进程同步问题。

二、实验内容及要求编制生产者—消费者算法,模拟一个生产者、一个消费者,共享一个缓冲池的情形。

1、实现对经典的生产者—消费者问题的模拟,以便更好的理解此经典进程同步问题。

生产者-消费者问题是典型的PV 操作问题,假设系统中有一个比较大的缓冲池,生产者的任务是只要缓冲池未满就可以将生产出的产品放入其中,而消费者的任务是只要缓冲池未空就可以从缓冲池中拿走产品。

缓冲池被占用时,任何进程都不能访问。

2、每一个生产者都要把自己生产的产品放入缓冲池,每个消费者从缓冲池中取走产品消费。

在这种情况下,生产者消费者进程同步,因为只有通过互通消息才知道是否能存入产品或者取走产品。

他们之间也存在互斥,即生产者消费者必须互斥访问缓冲池,即不能有两个以上的进程同时进行。

三、生产者和消费者原理分析在同一个进程地址空间内执行两个线程。

生产者线程生产物品,然后将物品放置在一个空缓冲区中供消费者线程消费。

消费者线程从缓冲区中获得物品,然后释放缓冲区。

当生产者线程生产物品时,如果没有空缓冲区可用,那么生产者线程必须等待消费者线程释放一个空缓冲区。

当消费者线程消费物品时,如果没有满的缓冲区,那么消费者线程将被阻挡,直到新的物品被生产出来。

四、生产者与消费者功能描述:生产者功能描述:在同一个进程地址空间内执行两个线程。

生产者线程生产物品,然后将物品放置在一个空缓冲区中供消费者线程消费。

当生产者线程生产物品时,如果没有空缓冲区可用,那么生产者线程必须等待消费者线程释放出一个空缓冲区。

消费者功能描述:消费者线程从缓冲区获得物品,然后释放缓冲区,当消费者线程消费物品时,如果没有满的缓冲区,那么消费者线程将被阻塞,直到新的物品被生产出来。

五、实验环境操作系统环境:Windows 系统。

编程语言:C#。

生产者与消费者实验报告

生产者与消费者实验报告

生产者和消费者实验报告【实验目的】1.加深对进程概念的理解,明确进程和程序的区别。

2.进一步认识并发执行的实质。

3.验证用信号量机制实现进程互斥的方法。

4.验证用信号量机制实现进程同步的方法。

【实验要求】用c语言编程搭建“生产者和消费者”经典进程通信问题的环境。

要求程序运行时,按任意键停止,显示当前系统的各个参数的值。

提交实验报告,以及相关程序列表。

打包成附件上传。

【实验环境】Visual C++6.0【实验内容】1.了解经典同步问题“生产者和消费者”生产者与消费者可以通过一个环形缓冲池联系起来,环形缓冲池由几个大小相等的缓冲块组成,每个缓冲块容纳一个产品。

每个生产者可不断地每次往缓冲池中送一个生产产品,而每个消费者则可不断地每次从缓冲池中取出一个产品。

指针i和指针j分别指出当前的第一个空缓冲块和第一个满缓冲块。

2.分析和理解(1)既存在合作同步问题,也存在临界区互斥问题合作同步:当缓冲池全满时,表示供过于求,生产者必须等待,同时唤醒消费者;当缓冲池全空时,表示供不应求,消费者应等待,同时唤醒生产者。

互斥:缓冲池显然是临界资源,所在生产者与消费都要使用它,而且都要改变它的状态。

(2)基于环形缓冲区的生产者与消费者关系形式描述:公用信号量mutex:初值为1,用于实现临界区互斥生产者私用信号量empty:初值为n,指示空缓冲块数目消费者私用信号量full:初值为0,指示满缓冲块数目整型量i和j初值为0,i指示首空缓冲块序号,j指示首满缓冲块序号(3)PV原语var mutex,empty,full:semaphore;i,j:integer;buffer:array[0...n-1] of item;i:=j:=1;Procedure producer;beginwhile true dobeginproduce a product;P(empty);P(mutex);buffer(i):=product;i:=(i+1) mod n;V(mutex);V(full);end;end;Procedure consumer;beginP(full);P(mutex);goods:=buffer(j);j:=(j+1) mod n;V(mutex);V(empty);consume a product;end;end;【实验源程序代码】#include <windows.h>#include <iostream>const unsigned short SIZE_OF_BUFFER = 10; //缓冲区长度unsigned short ProductID = 0; //产品号unsigned short ConsumeID = 0; //将被消耗的产品号unsigned short in = 0; //产品进缓冲区时的缓冲区下标unsigned short out = 0; //产品出缓冲区时的缓冲区下标int g_buffer[SIZE_OF_BUFFER]; //缓冲区是个循环队列bool g_continue = true; //控制程序结束HANDLE g_hMutex; //用于线程间的互斥HANDLE g_hFullSemaphore; //当缓冲区满时迫使生产者等待HANDLE g_hEmptySemaphore; //当缓冲区空时迫使消费者等待DWORD WINAPI Producer(LPVOID); //生产者线程DWORD WINAPI Consumer(LPVOID); //消费者线程int main(){//创建各个互斥信号g_hMutex = CreateMutex(NULL,FALSE,NULL);g_hFullSemaphore =CreateSemaphore(NULL,SIZE_OF_BUFFER-1,SIZE_OF_BUFFER-1,NULL);g_hEmptySemaphore =CreateSemaphore(NULL,0,SIZE_OF_BUFFER-1,NULL);//调整下面的数值,可以发现,当生产者个数多于消费者个数时,//生产速度快,生产者经常等待消费者;反之,消费者经常等待const unsigned short PRODUCERS_COUNT = 3; //生产者的个数const unsigned short CONSUMERS_COUNT = 1; //消费者的个数//总的线程数const unsigned short THREADS_COUNT =PRODUCERS_COUNT+CONSUMERS_COUNT;HANDLE hThreads[PRODUCERS_COUNT]; //各线程的handleDWORD producerID[CONSUMERS_COUNT]; //生产者线程的标识符DWORD consumerID[THREADS_COUNT]; //消费者线程的标识符//创建生产者线程for (int i=0;i<PRODUCERS_COUNT;++i){hThreads[i]=CreateThread(NULL,0,Producer,NULL,0,&producerID[i]); if (hThreads[i]==NULL) return -1;}//创建消费者线程for (i=0;i<CONSUMERS_COUNT;++i){hThreads[PRODUCERS_COUNT+i]=CreateThread(NULL,0,Consumer,NULL,0,& consumerID[i]);if (hThreads[i]==NULL) return -1;}while(g_continue){if(getchar()){ //按回车后终止程序运行g_continue = false;}}return 0;}//生产一个产品。

C语言编程模拟生产者及消费者问题

C语言编程模拟生产者及消费者问题

实验三编程模拟生产者和花费者问题一、实验目的和要求模拟实现用同步机构防止发生进度履行时可能出现的与时间相关的错误。

进度是程序在一个数据会合上运转的过程,进度是并发履行的,也即系统中的多个进度轮番地占用办理器运转。

我们把若干个进度都能进行接见和改正的那些变量称为公共变量。

因为进度是并发地履行的,因此,假如对进度接见公共变量不加限制,那么就会产生“与时间相关” 的错误,即进度履行后所获取的结果与接见公共变量的时间相关。

为了防备这种错误,系统一定要用同步机构来控制进度对公共变量的接见。

一般说,同步机构是由若干条原语——同步原语——所构成。

本实习要修业生模拟 PV操作同步机构的实现,模拟进度的并发履行,认识进度并发履行时同步机构的作用。

二、实验环境Windows操作系统和 Visual C++ 专业版或公司版三、实验步骤模拟 PV操作同步机构,且用PV操作解决生产者——花费者问题。

[提示]:(1)PV操作同步机构,由 P 操作原语和 V 操作原语构成,它们的定义以下:P 操作原语 P (s) :将信号量 s 减去 1,若结果小于 0,则履行原语的进度被置成等候信号量s 的状态。

V 操作原语 V (s) :将信号量 s 加 1,若结果不大于 0,则开释一个等候信号量 s 的进度。

这两条原语是以下的两个过程:procedure p (var s: semaphore);begin s: = s-1;if s<0 then W (s)end {p}procedure v (var s: semaphore);egin s: = s+1;if s£0 then R (s)end {v}此中 W(s)表示将调用过程的进度置为等候信号量s 的状态; R(s)表示开释一个等候信号量s 的进度。

在系统初始化时应把semaphore 定义为某个种类,为简单起见,在模拟实习中可把上述的 semaphore 直接改成 integer 。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

VC++学习:用vc 实现生产者消费者问题
文章来源:CSDN 作者:windcao
很多情况下我们需要多个线程互相协助,来完成同一个任务。

但是线程很难从外部进行控制。

利用线程同步技术可以使线程彼此交互,从而避免了外部控制对与时间和资源的浪费。

在实际工作过程中我就遇到了类似的问题,需要对共享的缓冲区进行操作。

有插入的线程也有读取的线程,这使我忽然想到了生产者和消费者。

我从MSDN 找到csdn 使用了各式各样的搜索引擎,只找到了很有现的关于CSemaphore 的资料。

////////////////////////////////////
// 生产者消费者问题
////////////////////////////////////
生产者要不断将数据放入共享的缓冲,消费者要不断从缓冲取出数据。

消费者必须等生产者
取走数据后才能再放新数据(不覆盖数据),消费者必须等生产者放入新数据后才能去取(不重复)。

/////////////////////////////////////
// 使用信号量的方法
/////////////////////////////////////
当线程使用指定数量的共享资源时,首先调用信号量的lock 方法"我能用资源吗"。

当有的空闲 共享资源时(此时计数器值>0)线程继续执行并且减少计数器的数量告诉其他线程"我用了××个资 源"。

否则挂起自己直到有足够的可用的资源为止。

当使用完资源时线程调用unlock 方法告诉其他 线程"我已经不用该资源了"。

/////////////////////////////////////
// 实现
////////////////////////////////////
///////////////////////////////////
1创建一个基于对话框的程序。

添加如下成员。

//////////////////////////////////
bool m_bSlow;//缓慢显示线程进行的结果
CProducerThread *m_pProducerThread;//生产者线程
CConsumerThread *m_pConsumerThread;//消费者线程
CSemaphore* m_pSemaphoreEmpty;//缓冲空的标志
CSemaphore* m_pSemaphoreFull;//缓冲满的标志
CMutex *m_pMutex;//互斥信号量
添加两编辑框用类向导,相关的添加成员
CString m_sBufCSM;//用来显示消费者取到的数据
CString m_sBuf;//显示生产者插入缓冲的数据
/////////////////////////////////////////////
2创建用户界面线程,生产者和消费者线程。

//////////////////////////////////////////// CProducerThread::CProducerThread(void* hParent) :m_pParentDlg(hParent)
{
}
int CProducerThread::Run()
{
CP_CDlg *pDlg;
pDlg=(CP_CDlg*)m_pParentDlg;
CSingleLock mutexLock(pDlg->m_pMutex);
for(int i=0;i<MAX_DATA_COUNT;I++){
pDlg->m_pSemaphoreEmpty->Lock(); mutexLock.Lock();
pDlg->m_sBuf.Format("%0.10d",i);
mutexLock.Unlock();
pDlg->m_pSemaphoreFull->Unlock();
}
return CWinThread::Run();
}
CConsumerThread::CConsumerThread(void *pParent) :m_pParent(pParent)
{
}
int CConsumerThread::Run()
{
CP_CDlg *pDlg;
pDlg=(CP_CDlg*)this->m_pParent;
char*pBuf;
pBuf=this->m_Data;
bool bSleep;
for(int i=0;i<MAX_DATA_COUNT;I+=10) {
pDlg->m_pSemaphoreFull->Lock();
pDlg->m_pMutex->Lock();
sprintf(pBuf,pDlg->m_sBuf);
bSleep=pDlg->m_bSlow ;
pDlg->m_pMutex->Unlock();
pBuf+=10;
if(pBuf>m_Data+CS M_BUF_COUNT-10)
pBuf=m_Data;
m_Data[CSM_BUF_COUNT]=0;
pDlg->m_pMutex->Lock();
sprintf(pDlg->m_sBufCSM.GetBuffer(CSM_BUF_COUNT+10),m_Data);
pDlg->m_pMutex->Unlock();
if (bSleep)
Sleep(100);
pDlg->m_pSemaphoreEmpty ->Unlock();
}
return CWinThread::Run();
}
///////////////////////////////////////
3启动线程:
///////////////////////////////////////
m_pSemaphoreFull =new CSemaphore(1,1);
m_pSemaphoreEmpty =new CSemaphore(0,1);
m_pMutex =new CMutex;
this->m_bUpdateAuto =false;
this->m_pProducerThread =new CProducerThread(this);
this->m_pConsumerThread =new CConsumerThread(this);
this->m_sBuf.Format("1234567890");
this->UpdateData(false);
this->m_pProducerThread->CreateThread(CREATE_SUSPENDED);
VERIFY(m_pProducerThread->SetThreadPriority(THREAD_PRIORITY_IDLE)); this->m_pConsumerThread->CreateThread(CREATE_SUSPENDED);
VERIFY(m_pConsumerThread->SetThreadPriority(THREAD_PRIORITY_IDLE)); this->m_pProducerThread->ResumeThread();
this->m_pConsumerThread->ResumeThread();。

相关文档
最新文档