2016-12-10 244 views
3

我想解决信号量在c#中的生产者 - 消费者并发性问题(我相信我解决了它:我相信信号量解决了互斥问题,同时它解决了同步问题的两个线程)。
我的问题是:
我不明白为什么我的变量“数据”通过引用(ref)在生产者实例和消费者实例中传递没有在内存中共享。
我只是一直在盯着C#几天,我很确定我没有正确理解关键字“ref”。请多多包涵。
代码:C#并发共享内存

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(); 
     } 
    } 
} 
} 

输出:
enter image description here

正如你可以看到生产者生产在内存的不同组成部分,消费者是看内存的不同部分。
我也很想知道如何解决这个问题。
谢谢!

+0

'this.data =数据;'那么你的数据不是由参了。它会将'data'复制到'this.data' –

+0

,但它只复制该值吗? – 00Mugen00

+0

有没有什么办法让this.data指向与生产者的构造函数中引用传递的变量“data”相同的内存。 – 00Mugen00

回答

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; 
    } 

    //... 
} 
+0

我喜欢这个主意。我要试一下。非常感谢你! – 00Mugen00

+0

它的工作原理!非常感谢你! – 00Mugen00

+0

很高兴帮助。不用谢。 –