gpt4 book ai didi

c# - 根据以下场景分配线程的最有效方法是什么?

转载 作者:行者123 更新时间:2023-11-30 22:34:51 24 4
gpt4 key购买 nike

我最多可以同时运行 5 个线程,这利用 5 个独立的硬件来加速一些复杂计算的计算并返回结果。每个硬件的 API(仅包含一种方法)不是线程安全的,并且在任何时间点只能在单个线程上运行。计算完成后,可以重新使用同一个线程在相同或不同的硬件上开始另一个计算,具体取决于可用性。每个计算都是独立的,不依赖于其他计算的结果。因此,最多 5 个线程可以按任何顺序完成其执行。

什么是最有效的 C#(使用 .Net Framework 2.0)编码解决方案来跟踪哪些硬件是空闲/可用的并将线程分配给适当的硬件 API 以执行计算?请注意,除了 5 个并发运行的线程的限制外,我无法控制线程何时以及如何被触发。

如果我错了请纠正我,但首选无锁解决方案,因为我相信它会提高效率和更具可扩展性的解决方案。

另请注意,这不是家庭作业,尽管听起来像是......

最佳答案

.NET 提供了一个线程池供您使用。 System.Threading.ThreadPool.QueueUserWorkItem() 告诉池中的线程为您做一些工作。

如果我设计这个,我不会专注于将线程映射到您的硬件资源。相反,我会为每个 HW 资源公开一个可锁定的对象——这可以只是一个包含 5 个对象的数组或队列。然后,对于您拥有的每一位计算,调用 QueueUserWorkItem()。在传递给 QUWI 的方法中,找到下一个可用的可锁定对象并将其锁定(也就是将其出列)。使用HW资源,然后重新入队对象,退出QUWI方法。

调用 QUWI 多少次并不重要;最多可以持有 5 个锁,每个锁都可以访问您的特殊硬件设备的一个实例。

doc page for Monitor.Enter()展示了如何创建一个可以被多个工作人员访问的安全(阻塞)队列。在 .NET 4.0 中,您将使用 the builtin BlockingCollection - 这是同一件事。

这基本上就是您想要的。除了不要调用 Thread.Create()。使用线程池。

引用:Advantage of using Thread.Start vs QueueUserWorkItem


// assume the SafeQueue class from the cited doc page. 
SafeQueue<SpecialHardware> q = new SafeQueue<SpecialHardware>()

// set up the queue with objects protecting the 5 magic stones
private void Setup()
{
for (int i=0; i< 5; i++)
{
q.Enqueue(GetInstanceOfSpecialHardware(i));
}
}


// something like this gets called many times, by QueueUserWorkItem()
public void DoWork(WorkDescription d)
{
d.DoPrepWork();

// gain access to one of the special hardware devices
SpecialHardware shw = q.Dequeue();
try
{
shw.DoTheMagicThing();
}
finally
{
// ensure no matter what happens the HW device is released
q.Enqueue(shw);
// at this point another worker can use it.
}

d.DoFollowupWork();
}

关于c# - 根据以下场景分配线程的最有效方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7651518/

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