我正在尝试用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();
}
}
}
}
如您所见,生产者正在内存的不同部分进行生产,而消费者正在查看内存的不同部分。
我也很想知道如何解决这个问题。
谢谢!
最佳答案
虽然您通过 ref 传递 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;
}
//...
}
关于c# - C# 并发中的共享内存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41080303/