读书人

OS中 生产消费者有关问题(同步有关问

发布时间: 2012-01-30 21:15:58 作者: rapoo

OS中 生产消费者问题(同步问题)请老师们提点 提点下 小弟先谢了!!!!
我先在的问题是 当资源栈满时这时生产者线程就会等待.空时消费者线程也会等待.. 但是在最后等待的线程不会再被唤醒..我用的是datagridview存放每一个操作者的步骤.但就是不会在显示等待的线程应该被唤醒再继续操作..
请老师指点指点谢谢

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Threading;
namespace spc_w1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}

private void Form1_Load(object sender, EventArgs e)
{
SharedControl();// 用来生成线程 和执行的.
sreen1(ShareArea.Dt);
}
public void sreen1(DataTable dt)
{
dataGridView1.AutoGenerateColumns = false;
dataGridView1.Columns[ "z1 "].DataPropertyName = "1 ";
dataGridView1.Columns[ "z2 "].DataPropertyName = "2 ";
dataGridView1.Columns[ "z3 "].DataPropertyName = "3 ";
dataGridView1.Columns[ "z4 "].DataPropertyName = "4 ";
dataGridView1.Columns[ "z5 "].DataPropertyName = "5 ";
dataGridView1.Columns[ "z6 "].DataPropertyName = "6 ";
dataGridView1.Columns[ "z7 "].DataPropertyName = "7 ";
dataGridView1.Columns[ "z8 "].DataPropertyName = "8 ";
dataGridView1.Columns[ "z9 "].DataPropertyName = "9 ";

dataGridView1.DataSource = dt;
}
private void SharedControl()


{
Thread[] ProThreads = new Thread[3];
Thread[] ConThreads = new Thread[2];

int i = 0;
for (i = 0; i < 3; i++)
{
producer Pro = new producer();
ProThreads[i]=new Thread(new ThreadStart(Pro.BufferPNum));
ProThreads[i].Name = "Pro " + i.ToString();
}
for (i = 0; i < 2; i++)
{
Consumer Con = new Consumer();
ConThreads[i] = new Thread(new ThreadStart(Con.BufferCNum));
ConThreads[i].Name = "Con " + i.ToString();
}
for (i = 0; i < 2; i++)
{
ConThreads[i].Start();

}
for (i = 0; i < 3; i++)
{
ProThreads[i].Start();

}


}




}
public class ShareArea//资源区 
{
    //它们全是静态的 
public static int[] Buffer;//缓冲区
public static int BufferSize;//缓冲区大小
public static int BufferCounts;//资源数量
public static int readP;//消费指针
public static int writeP;//生产指针
public static DataTable Dt;//用来显示动作的dt
static ShareArea()
{
Buffer =new int[5];
BufferSize = 5;
BufferCounts = 0;
readP = 0;
writeP = 0;
Dt = new DataTable();
Dt.Columns.Add( "1 ", typeof(string));
Dt.Columns.Add( "2 ", typeof(string));
Dt.Columns.Add( "3 ", typeof(string));
Dt.Columns.Add( "4 ", typeof(string));
Dt.Columns.Add( "5 ", typeof(string));
Dt.Columns.Add( "6 ", typeof(string));
Dt.Columns.Add( "7 ", typeof(string));
Dt.Columns.Add( "8 ", typeof(string));
Dt.Columns.Add( "9 ", typeof(string));
}

public static void print(string a)//显示操作的每一行
{
DataRow dr;
dr = Dt.NewRow();
dr[ "1 "] = a;


dr[ "2 "] = BufferCounts;
dr[ "3 "] = writeP.ToString();
dr[ "4 "] = readP.ToString();
int i=0;
int k=0;
for (i = 0; i < BufferSize; i++)
{
k=5+i;
if (Buffer[i] > 0)
dr[k.ToString()] = Buffer[i];
else dr[k.ToString()] = " ";
}
Dt.Rows.Add(dr);
}


}
public class producer// 生产者
{
public static int z=1;
private Random randomSleepTime;
public producer()
{
randomSleepTime = new Random();
}
public void bufferP()//生产
{
lock (this)
{
while (ShareArea.BufferCounts == ShareArea.BufferSize)
{
//不能生产,BUFFER是满的
string ss = " ";
ss += "Buffer是满的 ";


ss += Thread.CurrentThread.Name;
ss += "不能生产!等待.. ";
ShareArea.print(ss);
Monitor.Wait(this);
}

ShareArea.BufferCounts++;
ShareArea.Buffer[ShareArea.writeP] = z;

ShareArea.writeP = (ShareArea.writeP + 1) % ShareArea.BufferSize;
//生产成功。
//打印出有界缓冲区的全部内容,当前指针位置和生产者/消费者的标识符.
string ss1 = " ";
ss1 += Thread.CurrentThread.Name;
ss1 += "生产一个资源 " + z.ToString();
z++;
ShareArea.print(ss1);
Monitor.PulseAll(this);
}

}
public void BufferPNum()
{
int i = 0;
for (i = 0; i < 3;i++ )
{
bufferP();
Thread.Sleep(randomSleepTime.Next(1, 2000));
}


string sk3 = Thread.CurrentThread.Name + "生产完毕.. ";
ShareArea.print(sk3);
}
}
public class Consumer//消费者
{
private Random randomSleepTime;
public Consumer()
{
randomSleepTime = new Random();
}
public void bufferC()//消费
{
int bf = 0;
lock (this)
{
while (ShareArea.BufferCounts == 0)
{
//不能消费,生产者没生产出产品;
string ss = " ";
ss += "Buffer是空的 ";
ss += Thread.CurrentThread.Name;
ss += "不能消费!等待.. ";
ShareArea.print(ss);
Monitor.Wait(this);
}

ShareArea.BufferCounts--;
bf = ShareArea.Buffer[ShareArea.readP];
ShareArea.readP = (ShareArea.readP + 1) % ShareArea.BufferSize;



//消费成功。
//打印出有界缓冲区的全部内容,当前指针位置和生产者/消费者的标识符.
string ss2 = " ";
ss2 += Thread.CurrentThread.Name;
ss2 += "消费一个资源 " + bf.ToString();
ShareArea.print(ss2);
Monitor.PulseAll(this);
}

}
public void BufferCNum()
{
int i = 0;
for (i = 0; i <4; i++)
{
Thread.Sleep(randomSleepTime.Next(1, 2000));
bufferC();
}
string sk2 = Thread.CurrentThread.Name+ "消费完毕.. ";
ShareArea.print(sk2);
}
}

}

[解决办法]
你的 Monitor.Wait(this); 和 Monitor.PulseAll(this); 都在一个线程里,如果程序走到Monitor.Wait(this)就被阻塞在那里,永远也执行不到Monitor.PulseAll(this),也就是说此线程永远不会被唤醒.


Monitor.Wait(this); 和 Monitor.PulseAll(this) 通常是用在不同线程之间传递共享资源信息的.

读书人网 >C#

热点推荐