我试图用c#中的信号量解决生产者 - 消费者并发问题(我相信我解决了它:我相信信号量解决了互斥问题,同时它解决了两者的同步问题线程)。
我的问题是:
我不明白为什么我的变量"数据"生产者实例中的引用(ref)传递,并且消费者实例中的内容不在内存中共享
我只学了几天C#,我很确定我不理解关键词" ref"正常。请耐心等待。
代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace ProducerConsumer
{
class Program
{
static void Main(string[] args)
{
Semaphore hasData = new Semaphore(0, 1); //There is no data when the program starts
Semaphore hasSpace = new Semaphore(1, 1); //There is space to produce
int data = 0; //the variable "data" will be a shared variable
Producer producer = new Producer(hasData, hasSpace, ref data);
Consumer consumer = new Consumer(hasData, hasSpace, ref data);
Thread producerThread = new Thread(new ThreadStart(producer.Produce));
Thread consumerThread = new Thread(new ThreadStart(consumer.Consume));
producerThread.Start();
consumerThread.Start();
}
}
class Producer
{
static Random rnd = new Random();
private Semaphore hasData;
private Semaphore hasSpace;
private int data;
public Producer(Semaphore hasData, Semaphore hasSpace, ref int data)
{
this.hasData = hasData;
this.hasSpace = hasSpace;
this.data = data;
}
public void Produce()
{
while (true)
{
hasSpace.WaitOne();
this.data = rnd.Next(0, 100);
Console.WriteLine("The producer made: " + this.data);
Thread.Sleep(5000);
hasData.Release();
}
}
}
class Consumer
{
private Semaphore hasData;
private Semaphore hasSpace;
private int data;
public Consumer(Semaphore hasData, Semaphore hasSpace, ref int data)
{
this.hasData = hasData;
this.hasSpace = hasSpace;
this.data = data;
}
public void Consume()
{
while (true)
{
hasData.WaitOne();
Console.WriteLine("The consumer got: " + this.data);
Thread.Sleep(5000);
hasSpace.Release();
}
}
}
}
正如您所看到的那样,制作人在内存的不同部分进行制作,而消费者正在查看内存的不同部分。
我也很想知道如何解决这个问题
谢谢!
答案 0 :(得分:0)
虽然您通过引用传递data
,但其值会复制到data
字段中。因为int
是值类型而不是引用类型。
您可以使用包装类将值保存在引用类型中。
class RefVal<T>
{
public T Value { get; set; }
public RefVal(T value)
{
Value = value;
}
public override string ToString()
{
return Value.ToString();
}
}
然后你必须使用它代替int
这样的
RefVal<int> data = new RefVal<int>(0); //the variable "data" will be a shared variable
Producer producer = new Producer(hasData, hasSpace, data);
Consumer consumer = new Consumer(hasData, hasSpace, data);
// ...
class Producer
{
private RefVal<int> data;
// ...
public Producer(Semaphore hasData, Semaphore hasSpace, RefVal<int> data)
{
this.hasData = hasData;
this.hasSpace = hasSpace;
this.data = data;
}
public void Produce()
{
while (true)
{
hasSpace.WaitOne();
this.data.Value = rnd.Next(0, 100); // set value to .Value
Console.WriteLine("The producer made: " + this.data);
Thread.Sleep(5000);
hasData.Release();
}
}
}
class Consumer
{
private Semaphore hasData;
private Semaphore hasSpace;
private RefVal<int> data;
public Consumer(Semaphore hasData, Semaphore hasSpace, RefVal<int> data)
{
this.hasData = hasData;
this.hasSpace = hasSpace;
this.data = data;
}
//...
}