C#并发中的共享内存

时间:2016-12-10 21:02:48

标签: c# concurrency

我试图用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();
        }
    }
}
}

输出:
enter image description here

正如您所看到的那样,制作人在内存的不同部分进行制作,而消费者正在查看内存的不同部分。
我也很想知道如何解决这个问题 谢谢!

1 个答案:

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

    //...
}