You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#双线程读写float值异常:BufferData仅填充单一数值求解

问题根源

你的核心问题不是线程同步的语法错误,而是对线程执行速度的认知偏差,以及填充数组的逻辑不符合需求:

  1. Thread2的数组填充循环(524288次迭代)执行速度极快,远超过Thread1写入_readWriteValue的频率。在一次数组填充过程中,Thread1大概率只能完成0次或1次写入,导致整个数组被同一个值填满。
  2. 另外,_readWriteValue和_stop没有标记为volatile,可能存在CPU缓存一致性问题,导致Thread2无法及时看到Thread1的最新写入,但这不是当前现象的主要原因。
解决方案

根据你的需求(Thread1生成随机值,Thread2收集足够多的随机值后批量处理),正确的做法是用生产者-消费者模式,让Thread1生产的每个随机值都被收集,直到攒够BUFFER_SIZE个再处理。

修正后的代码示例

private const int BUFFER_SIZE = 65536 * 8;
private readonly ConcurrentQueue<float> _valueQueue = new ConcurrentQueue<float>();
private volatile bool _stop = false;

private void Thread1()
{
    Random ran = new Random();
    while (!_stop)
    {
        // 生产随机值并加入队列
        _valueQueue.Enqueue(ran.Next(1, 100));
        // 可根据需求添加适当延迟,避免队列增长过快
        // Thread.Sleep(1);
    }
}

private void Thread2()
{
    while (!_stop)
    {
        float[] bufferData = new float[BUFFER_SIZE];
        int filledCount = 0;
        
        // 从队列中取足够多的值填充数组
        while (filledCount < BUFFER_SIZE && !_stop)
        {
            if (_valueQueue.TryDequeue(out float value))
            {
                bufferData[filledCount++] = value;
            }
            else
            {
                // 队列空时短暂等待,避免空转占用CPU
                Thread.SpinWait(10);
            }
        }
        
        if (filledCount == BUFFER_SIZE)
        {
            ProcessMethod(bufferData);
        }
    }
}

private void ProcessMethod(float[] data)
{
    // 处理逻辑
}

关键调整点

  • 用ConcurrentQueue作为生产者(Thread1)和消费者(Thread2)的中间缓冲区,确保每个生成的随机值都能被收集。
  • Thread2不再直接读取共享变量,而是从队列中取已生成的随机值,直到填满数组再处理。
  • _stop标记为volatile,确保线程间的可见性。
  • 添加了空队列时的等待逻辑,避免Thread2空转消耗CPU。

其他注意事项

  • 如果不需要严格的实时性,可以在Thread1中添加适当延迟,控制随机值的生成速度,避免队列无限增长。
  • 若要保证单个变量的线程安全访问,也可以用Interlocked类或lock块保护读写操作,但这解决不了你当前数组全是同一个值的问题——核心是填充逻辑的设计偏差,而非同步语法错误。

内容的提问来源于stack exchange,提问作者Alireza Izadimehr

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 00:06:00