2016-12-10 174 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

很高興幫助。不用謝。 –