C# 为未知的预先线程执行更高优先级的线程

C# 为未知的预先线程执行更高优先级的线程,c#,.net,multithreading,C#,.net,Multithreading,我创建了大约5000名后台工作人员,他们在控制台应用程序中进行密集工作。我还使用一个外部库来实例化一个对象,比如ObjectX。在某个时刻,比如t0,ObjectX试图从os线程池获取一个线程并启动它,但我无法控制它如何获取这个线程。对于100名背景工作者来说,一切都很顺利。对于1000名后台工作人员,ObjectX在t0之后大约需要10分钟才能获得并启动线程 有没有一种方法可以预先为将来由对象启动的任何线程设置高优先级 因为我认为1的答案是“不”,有没有办法限制背景工作者的优先权,以便以某种方

我创建了大约5000名后台工作人员,他们在控制台应用程序中进行密集工作。我还使用一个外部库来实例化一个对象,比如ObjectX。在某个时刻,比如t0,ObjectX试图从os线程池获取一个线程并启动它,但我无法控制它如何获取这个线程。对于100名背景工作者来说,一切都很顺利。对于1000名后台工作人员,ObjectX在t0之后大约需要10分钟才能获得并启动线程

  • 有没有一种方法可以预先为将来由对象启动的任何线程设置高优先级

  • 因为我认为1的答案是“不”,有没有办法限制背景工作者的优先权,以便以某种方式支持其他一切?尽管我只想“喜欢”ObjectX

  • 目标是始终拥有可用的资源来运行ObjectX启动的线程,无论机器负载有多大

    我正在Windows 64位机器上使用C#和.Net fr 3.5

    目标是始终拥有可用的资源来运行ObjectX启动的线程,无论机器负载有多大

    那么线程优先级可能不是正确的工具

    一般来说,windows不是实时操作系统;特别是,win32甚至不尝试软实时(IIRC,NT内核在某些时候尝试至少支持软实时子系统,但我可能错了)。因此,无法保证可用资源或时间

    另外,您是否担心系统中的其他线程?这些线程超出了您的控制(如果其他线程已经处于系统最大优先级怎么办?)。 如果您担心应用程序中的线程。。。您可以控制和限制它们,使用更少的线程/工作线程来做更多的工作(例如,以更大的单元批处理工作,并将其提交给工作线程,或者使用TPL或其他工具来处理和限制线程的使用)


    也就是说,您可以在创建线程时进行拦截(例如,查看这个问题),查看它是否是为ObjectX创建的(例如,检查它的名称),并使用SetThreadPriority来提升它。

    线程的工作方式是操作系统为它们提供处理器时间。发生这种情况时,称为上下文切换。上下文切换大约需要2000-8000个周期(即取决于处理器2000-8000指令)。如果操作系统有许多CPU或内核,它可能不需要将CPU从一个线程转移到另一个线程——避免上下文切换。每个CPU一次只能运行一个线程,当需要CPU的线程多于CPU的线程时,就强制进行上下文切换。上下文切换的执行速度不超过系统量程(客户端每20毫秒一次,服务器每120毫秒一次)

    如果你有5000个后台工作人员,你实际上有5000个线程。这些线程中的每一个都可能在争夺CPU时间。在客户端版本的windows上,这意味着每秒250000次上下文切换。i、 e.每秒500000000到2000000000个周期仅用于线程之间的切换。(即,在线程执行的工作之外)如果它甚至可以每秒处理那么多上下文切换

    建议的做法是每个处理器只有一个CPU绑定线程。CPU绑定线程是一个花费很少时间“等待”的线程。UI线程不是CPU绑定的线程。如果您的后台工作线程花费大量时间等待锁,那么它们也可能不受CPU限制——但一般来说,后台工作线程受CPU限制。(否则,使用后台工作人员有什么意义?)

    此外,操作系统会花费大量时间来确定下一个线程需要什么样的CPU。当您开始更改线程优先级时,您会对此产生干扰,大多数情况下会使整个系统变慢(不仅仅是应用程序),而不是变快

    更新: 在相关的not上,创建一个新线程大约需要200000个周期,销毁一个线程大约需要100000个周期

    更新2:
    如果问题的动力不仅仅是“如果可以做到”,而是能够扩展工作负载,那么正如@JoshW/@Servy所提到的,使用生产者/消费者模式之类的东西将允许可扩展性,这将有助于通过队列或服务总线水平扩展到多台计算机/节点。简单地启动同数量的线程是不可扩展的,超出了CPU的范围。如果你真正想要的是一个可以扩展的架构,因为“可用资源…机器有多过载”是不可能的。。。考虑到您对其他答案的评论以及您的请求“无论有多少后台工作人员创建,ObjectX都会尽快运行”。。。您可以使用ManualResetEvent强制后台工作人员进行阻止

    例如,在工作代码的顶部,可以使用WaitOne方法阻止手动重置事件。此手动重置可以是静态的,也可以作为输入参数传递,无论您的ObjectX在何处被实例化/调用,或者在ManualResetEvent上调用.reset方法。这会阻止你所有的工人在WaitOne排队。接下来,在运行ObjectX的代码的底部,调用ManualResetEvent.Set()方法,该方法将解除对Worker的阻止


    请注意,这不是管理线程的有效方法,但如果您“必须让它工作”,并且以后有时间改进它。。。我想这是一个可能的解决方案。

    我们需要知道您使用的语言或平台。5000名后台工作人员。。。疯狂…@user2161465更多工人!=还有更多的工作要做。比如说,坚持雇佣合理数量的工人。。10? (核数N的上限*2是一个很好的经验法则)@user2161465您需要创建它们,但不需要实际运行它们。然而,这是不可能的