2016-12-10 16 views
3

私はセマフォをC#でセマフォを使って解決しようとしています(私はそれを解決したと信じています。 2つのスレッドのうちの1つ)。
私の問題は次のとおりです。
プロデューサインスタンスとコンシューマインスタンスの参照(ref)によって渡された変数 "data"がメモリ内で共有されていない理由を理解できません。
私は数日間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 =データを、それを使用する必要があります;'その後、あなたのデータはもう参照によるものです。 'データ'を 'this.data' –

+0

にコピーしますが、値をコピーするだけですか? – 00Mugen00

+0

this.dataが、プロデューサのコンストラクタで参照渡しされる変数 "data"と同じメモリを参照する方法はありますか。 – 00Mugen00

答えて

0

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

    //... 
} 
+0

私はこのアイデアが大好きです。私はそれを試みるつもりです。どうもありがとうございました! – 00Mugen00

+0

それは動作します!どうもありがとうございました! – 00Mugen00

+0

うれしかったです。どういたしまして。 –

関連する問題