gpt4 book ai didi

c# - 最多 N 个线程以 FIFO 顺序执行的代码部分

转载 作者:塔克拉玛干 更新时间:2023-11-03 03:44:40 24 4
gpt4 key购买 nike

我有一段代码应该由小于 N 的最大线程数执行,并且线程调用 someFunction() 的顺序应该反射(reflect)在它们进入该部分的顺序中,即先进先出顺序。

如果我使用 Semaphore我无法控制线程进入该部分的顺序。

"There is no guaranteed order, such as FIFO or LIFO, in which blocked threads enter the semaphore."

最初的尝试:

class someClass
{
static volatile Semaphore semaphore;
...

someClass()
{
semaphore = new Semaphore(N,N)
}

someType someFunction(InputType input)
{
try
{
semaphore.WaitOne();
/* Section Begins */
var response = someHeavyJob(input); // submitted to the server
return response;
/* Section Ends */
}
finally
{
semaphore.Release();
}
}
}

如果我按如下方式组合信号量和 ConcurrentQueue,线程可能会返回对其他线程带来的请求的响应,这将需要对代码的其他部分进行重大更改。以下问题的 .NET 4.5 解决方案是什么:

  1. 允许代码段中的最大线程数小于N
  2. 线程进入该部分的顺序是 FIFO
  3. 线程会得到自己带来的请求的响应(而不是其他线程带来的请求的响应)

    class someClass
    {
    static volatile ConcurrentQueue<someType> cqueue;
    static volatile Semaphore semaphore;
    ...

    someClass()
    {
    cqueue = new ConcurrentQueue<someType>();
    semaphore = new Semaphore(N,N)
    }

    someType someFunction(Request request)
    {
    try
    {
    cqueue.enqueue(request);
    semaphore.WaitOne();
    Request newrequest;
    cqueue.TryDequeue(out newrequest);

    /* Section Begins */

    var response = someHeavyJob(Request newrequest); // submitted to the server
    return response;
    /* Section Ends */
    }
    finally
    {
    semaphore.Release();
    }
    }
    }

更新:我正在澄清我的问题:SomeHeavyJobs() 函数是对正在处理此作业的服务器的阻塞调用。

更新 2:谢谢大家的回答。作为记录:我最终使用了 FIFO Semaphore

最佳答案

“如果我按如下方式组合信号量和 ConcurrentQueue,线程可能会返回对其他线程带来的请求的响应,这将需要对代码的其他部分进行重大更改。”

我不想这么说,但我会建议“更改代码的其他部分”,尽管我不知道这会有多大的“重要性”。

通常,如您所建议的那样,通过排队包含对原始类实例的引用的消息来满足这样的要求,以便可以将响应“返回”给请求它们的对象。如果发起者都是某个“messagehandler”类的后代,那么调用该函数的线程(应该是 messagehandler 的成员)就更容易了。一旦线程执行了该功能,它们就可以调用消息处理程序的“onCompletion”方法。 'onCompletion' 可以表示发起者正在等待的事件(同步),或者将某些内容排队到发起者的私有(private) P-C 队列(异步)。

因此,一个 BlockingCollection、一个消费者线程和 C++/C# 继承/多态性的明智使用应该可以完成这项工作。

奇怪的是,这几乎正是我在当前的嵌入式 ARM 项目中被迫做的事情。用于 config/debug/log 的命令行界面线程现在非常大,需要 600 字的大量堆栈,即使在“Thumb,Optimize of size”模式下也是如此。它不再被允许直接调用 SD 文件系统,现在必须将自己排入运行 SD 卡的线程(它在系统中具有最大的堆栈以运行 FAT32),并等待 SD 线程的信号量调用它的方法并在完成时向信号量发出信号。

这是确保调用按顺序进行并始终有效的经典方法。它基本上是一个只有一个线程的线程池。

就像其他张贴者所写的那样,任何其他方法都可能是,呃……“勇敢”。

关于c# - 最多 N 个线程以 FIFO 顺序执行的代码部分,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11049221/

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