gpt4 book ai didi

c# - 在队列上运行多个线程的情况下访问 ConcurrentQueue 的最新元素

转载 作者:太空宇宙 更新时间:2023-11-03 11:36:49 25 4
gpt4 key购买 nike

我们有一个 ConcurrentQueue 用于在 3 个线程之间共享数据。线程 A 不断地用数据填充队列。线程 B 旨在将此数据记录到文件中。线程 C 应该检索队列中最年轻的条目(或尽可能接近最年轻的条目),对其执行一些操作并在屏幕上显示结果。

线程B,为了及时对文件写操作进行集群,做了这样的事情:

if (cq.Count > 100)
{
while (cq.Count > 1)
{
qElement = PopFromCq(cq); // PopFromCq uses cq.TryDequeue()
bw.Write(qElement.data); // bw is a binary writer
}
}
else
{
System.Threading.Thread.Sleep(10);
}

也就是说,它等待至少 100 个元素排队,然后将它们写入磁盘。它始终在队列中保留至少一项,原因是因为我们希望线程 C 始终可以访问至少一项。

线程 C 中的循环如下所示:

while (threadsRunning) 
{
System.Threading.Thread.Sleep(500); // Update twice per second
ProcessDataAndUpdateScreen(cq.ElementAt(cq.Count - 1)); // our terrible attempt at looking at the latest (or close to latest) entry in the queue
}

在此循环中,由于将数据写入磁盘的线程与 cq.ElementAt(cq.Count-1) 调用之间的竞争,我们有时会遇到异常。我相信正在发生的事情如下:

  1. cq.Count 计算为 90。
  2. 此时,线程 B 已经开始循环,它正在从队列中取出数据写入磁盘
  3. 在调用 cq.ElementAt() 时,线程 B 消耗了一些项目,使得 (cq.Count - 1) 不再指向队列中的有效条目。

对于在队列上运行多个线程的情况下访问队列中最年轻条目的最佳方式有什么想法吗?

问候,

最佳答案

A-B通信和A-C通信是否都需要经过队列?如果您有线程 A 将每个条目写入队列(供 B 读取和记录)并将条目保存在某处的 volatile 属性中,该怎么办?每次 C 想要获取最年轻的元素时,它可以直接从该属性读取。

编辑:您实际上应该使用 Interlocked.CompareExchange<T>(T, T),而不是仅仅依赖于 volatile 属性。设置和读取“最年轻的条目”属性。

关于c# - 在队列上运行多个线程的情况下访问 ConcurrentQueue 的最新元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6008754/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com