代码之家  ›  专栏  ›  技术社区  ›  HaveThunk

在多线程工作队列处理器中管理线程池不足?

  •  3
  • HaveThunk  · 技术社区  · 16 年前

    我正在研究工作队列处理器的设计,其中队列处理器从队列中检索命令模式对象并在新线程中执行它。

    我正试图解决一个潜在的队列锁定场景,其中嵌套的命令可能导致死锁。

    例如。

    foocommand对象被放置到队列中,然后队列处理器在自己的线程中执行该队列。

    执行的foocommand将barcommand放到队列中。

    假设允许的最大线程数只有1个线程,则队列处理器将处于死锁状态,因为foocommand正在无限等待barcommand完成。

    如何管理这种情况?队列对象是作业的正确对象吗?是否有任何可用于解决此问题的支票和余额?

    多谢。(应用程序使用C.NET 3.0)

    5 回复  |  直到 16 年前
        1
  •  1
  •   Guvante    16 年前

    对于这种简单的情况,一个额外的监视线程可以根据需要分离出更多的线程是有帮助的。

    基本上每N秒检查一次作业是否完成,如果没有,则添加另一个线程。

    这不一定能处理更复杂的死锁问题,但它可以解决这个问题。

    我对更严重的问题的建议是将等待限制到新生成的进程,换句话说,您只能等待您启动的某个东西,这样就永远不会出现死锁,因为在这种情况下循环是不可能的。

        2
  •  2
  •   Khoth    16 年前

    您可以重新设计一些东西,使foocommand不使用队列来运行barcommand,而是直接运行它,或者您可以将foocommand拆分为两部分,并在将barcommand排队后立即停止前半部分,并在完成foocommand的工作后让barcommand队列成为第二部分。

        3
  •  2
  •   jan.vdbergh    16 年前

    排队隐式地假定异步执行模型。通过等待命令退出,您可以同步工作。

    也许您可以将命令分为三部分:执行到必须发送barcommand为止的foocommand1、barcommand,最后是在barcommand完成后继续执行的foocommand2。这三个命令可以单独排队。当然,barcommand应该确保foocommand2排队。

        4
  •  1
  •   hfcs101    16 年前

    如果您自己构建队列对象,可以尝试以下几种方法:

    1. 动态添加新的服务线程。如果可用线程计数为零的时间过长,请使用计时器并添加线程。
    2. 如果一个命令试图将另一个命令排队并等待结果,那么您应该在同一线程中同步执行第二个命令。如果第一个线程只是等待第二个线程,那么您无论如何也不会获得并发优势。
        5
  •  1
  •   mancaus    16 年前

    我假设您希望将barcommand排队,以便它能够与foocommand并行运行,但是barcommand稍后将需要结果。如果是这种情况,那么我建议使用并行扩展库中的Future。

    Bart Desmet有一个 good blog entry 对此。基本上你想做的是:

    
    public void FooCommand()
    {
        Future<int> BarFuture = new Future<int>( () => BarCommand() );
    
        // Do Foo's Processing - Bar will (may) be running in parallel
    
        int barResult = BarFuture.Value;
    
        // More processing that needs barResult
    }
    

    使用类似并行扩展的libararies,我可以避免“滚动您自己的”调度。