c# - C# 并发中的共享内存

标签 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

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

最佳答案

虽然您通过 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/

相关文章:

java - 同步 : Threads execute two critical sections in same order

java - ConcurrentHashMap 原子获取、增量和替换

java - 保证回调总是异步执行的最佳方式?

c# - 统一: Wrap mesh softly around other mesh?

c# - 对于 64 位架构上的算术,.NET 是否将 Int32 提升为 Int64?

c# - Nuget 错误 : Failed to add reference to System.Net.Http

java - Docx4j 库不是线程安全的。解决此问题的可能方法有哪些?

播放 JMF 视频时更新视频控制 UI 时出现 Java 并发问题

插入 SQL 数据库时 C# 嵌套 Parallel.ForEach

c# - 无法在xml中的指定位置插入节点