C#-多线程
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
多线程处理消费者生产者问题
1、题目的内容及要求
生产者/消费者问题
1.可以产生多个生产者和消费者线程;
2.生产者和消费者共享一个缓冲;
3.生产者产生一个数据(可以是一个整数),然后将该数据放入缓冲,当多个生产者并发运行时,不能多个生产者将数据放入缓冲的同一个位置(并发的概念自行百度);
4.消费者从缓冲提取数据,多个并发的消费者不能提取缓冲同一位置的数据,当提取后该数据从缓冲中删除(不一定物理删除,可能只是改一个下标);
5.当缓冲满后生产者休眠,当缓冲空后消费者休眠;
6.生产者运行达到一定时间后(不同生产者随机设定)结束自身线程,如果没有生产者并且缓冲为空,消费者结束自身线程;
7.最终统计生产者产生数据的个数、消费者消费数据的个数、缓冲数据的个数,看是否一致。
2、需求分析
1、生产者产生一个数据(可以是一个整数),然后将该数据放入缓冲,当多个生产者并发运行时,不能多个生产者将数据放入缓冲的同一个位置(并发的概念自行百度);
2、消费者从缓冲提取数据,多个并发的消费者不能提取缓冲同一位置的数据,当提取后该数据从缓冲中删除(不一定物理删除,可能只是改一个下标);
3、当缓冲满后生产者休眠,当缓冲空后消费者休眠;
4、生产者运行达到一定时间后(不同生产者随机设定)结束自身线程,如果没有生产者并且缓冲为空,消费者结束自身线程;
5、统计生产者产生数据的个数、消费者消费数据的个数、缓冲数据的个数,看是否一致。
3、程序设计(画自己的程序流程图或者介绍自己的功能模块,对程序做简单的介绍)
4、概要设计
(1)采用线程的同步和互斥
(2)生产者消费者,是在多线程同步的一个问题,两个固定大小缓冲区的线程,在实际运行是会发生问题,生产者是生成数据放入缓冲区,重复过程,消费者在缓冲区取走数据。(3)为使生产者和消费者不造成死锁需要开锁:
public int Buffer
{
get
{
int temp;
// 加锁
lock (this)
{
while (BufferCount == 0)
{ //多个消费者,所以此处改用while
Console.WriteLine( + " 尝试去消费");
Console.WriteLine("缓冲区为空" + + " 等待");
Monitor.Wait(this);
// 为临界区之外等待的生产者放行,让他来"生产"
// 一直到生产者生产结束,调用了Monitor.PauseAll()
// 才能继续执行下去,此时,消费者自动重新获得this的锁
}
--BufferCount;
temp = buffer[getPosition];
getPosition = (getPosition + 1) % buffer.Length;
DisplayState(Thread.CurrentThread.Nam e + " 消费了" + temp);
5、源代码
public class Synchronized
{
private int[] buffer; //缓冲区
private int BufferCount = 0;
private int getPosition = 0, setPosition = 0;
//下一个读到的位置和写到的位置
public Synchronized(int capacity)
{
buffer = new int[capacity];
}
public int BufferSize
{
get
{
return buffer.Length;
}
}
public int Buffer
{
get
{
int temp;
// 加锁
lock (this)
{
while (BufferCount == 0)
{ //多个消费者,所以此处改用while
Console.WriteLine( + " 尝试去消费");
Console.WriteLine("缓冲区为空" + + " 等
待");
Monitor.Wait(this);
// 为临界区之外等待的生产者放行,让他来"生产"
// 一直到生产者生产结束,调用了Monitor.PauseAll()
// 才能继续执行下去,此时,消费者自动重新获得this的锁
}
--BufferCount;
temp = buffer[getPosition];
getPosition = (getPosition + 1) % buffer.Length;
DisplayState( + " 消费了" + temp);
// 通知,让等待的生产者线程进入Started状态,如果生产者处于临界区之外,这句话执行完后他仍然在临界区之外
Monitor.PulseAll(this);
// 释放锁
}//lock
return temp;
}
set
{
// 加锁
lock (this)
{
while (BufferCount == buffer.Length)
{
Console.WriteLine( + " 尝试去生产");
Console.WriteLine("缓冲区满" + + "等待");
Monitor.Wait(this);
// 为临界区之外等待消费者放行,让他来"消费"
// 一直到消费者调用了Monitor.Pause()
// 才能继续执行下去,此时,生产者自动重新获得this的锁
}
buffer[setPosition] = value;
++BufferCount;
setPosition = (setPosition + 1) % buffer.Length;
DisplayState( + " 生产了" + value);
// 通知,让Wait状态的消费者进入Started状态,如果消费者处于临界区之外,这句话执行完后他仍然在临界区之外
Monitor.PulseAll(this);
// 释放锁