提升线程:是不是可以在移动到另一个线程之前限制线程的运行时间

Posted

技术标签:

【中文标题】提升线程:是不是可以在移动到另一个线程之前限制线程的运行时间【英文标题】:Boost threads: is it possible to limit the run time of a thread before moving to another thread提升线程:是否可以在移动到另一个线程之前限制线程的运行时间 【发布时间】:2010-09-18 23:56:40 【问题描述】:

我有一个带有 main 线程和 diagnostics 线程的程序。主线程基本上是一个执行各种任务的while(1) 循环。其中一项任务是为诊断引擎提供有关系统的信息,然后稍后再检查(即在下一个循环中)以查看是否有任何问题需要处理。主循环的迭代不应超过 0.1 秒。如果一切正常,那么诊断引擎几乎不会花时间返回答案。但是,如果出现问题,诊断引擎可能需要几秒钟来隔离问题。因此,每次诊断引擎接收到新信息时,它都会启动一个新的诊断线程。

我们遇到的问题是诊断线程正在从主线程中窃取时间。实际上,即使我们有两个线程,主线程也无法像我希望的那样频繁运行,因为诊断线程仍在旋转。

使用 Boost 线程,是否可以限制一个线程在移动到另一个线程之前可以运行的时间量?这里同样重要的是我们使用的诊断算法是黑盒,所以我们不能在里面放任何线程代码。谢谢!

【问题讨论】:

【参考方案1】:

如果您运行多个线程,它们确实会消耗 CPU 时间。如果您只有一个处理器,并且一个线程正在执行处理器密集型工作,那么该线程将减慢在其他线程上完成的工作。如果您使用特定于操作系统的工具来更改线程优先级,那么您可以使诊断线程的优先级低于主线程。此外,您提到诊断线程正在“旋转”。你的意思是说它实际上相当于这样的旋转等待:

while(!check_done()) ; // loop until done

如果是这样,我强烈建议您尽量避免这种忙等待,因为它会消耗 CPU 时间而没有任何效果。

但是,尽管多个线程可能会导致彼此变慢,但如果您看到几秒钟的实际延迟,这表明存在另一个问题,并且主线程实际上正在等待诊断线程完成。检查诊断线程对join() 的调用是否在主循环之外。

另一种可能性是诊断线程正在锁定主线程循环所需的互斥锁。检查哪些互斥锁被锁定以及在哪里锁定。

要真正提供帮助,我需要查看一些代码。

【讨论】:

【参考方案2】:

看起来你的线程是互锁的,所以你的主线程一直等到后台线程完成它的工作。检查任何可能导致此问题的多线程同步。

检查它与操作系统调度无关,在双核系统上运行您的程序,因此两个线程可以真正并行执行

【讨论】:

这正是我的想法,但在主循环中我查询诊断循环以查看它是否已经很忙。当它很忙时,我将这条消息打印到屏幕上。在我的程序似乎挂起的情况下,我至少会看到一个,但有时会看到几个“诊断线程正忙”消息。也许它仍然是别的东西,但我认为如果检查返回为 busy 那么我不会做任何会干扰该线程的其他事情。【参考方案3】:

从您提出问题的方式来看,您似乎不太确定线程是如何工作的。我假设“一个线程在移动到另一个线程之前可以运行的时间量”是指每个线程花费的 cpu 周期数。这种情况每秒发生数十万次。

Boost.Thread 不支持线程优先级,尽管特定于操作系统的线程 API 支持。但是,您的问题似乎表明有必要进行基本的重新设计 - 或者至少需要进行大量分析以找到瓶颈。

【讨论】:

因为我对线程编程很陌生,所以我肯定有可能误解了一些事情。但是,您引用的示例更可能是一个糟糕的选择。如果我有线程 A 和线程 B,那么我希望操作系统能够很快地在 A 和 B 之间来回切换,这样对于线程 A 中的 GUI 用户来说,A 似乎总是打开的。在我的情况下,操作系统似乎允许线程 B 在切换回线程 A 之前运行 2 秒。为什么会这样? (另外,如果我仍然对某些线程问题感到困惑,请告诉我。) 线程不会像这样阻塞。您的操作系统不应该允许这样做。但是,应该可以使用您的分析器来确定每个线程所花费的实际时间。 我从未使用过探查器。有什么建议吗?我的 IDE 是 Eclipse CDT,我使用的是 gnu 工具链(gcc、g++、make、gdb)。【参考方案4】:

您通常无法在操作系统级别执行此操作,因此我怀疑 boost 是否有任何特定的限制执行时间。你可以用小块操作和等待来伪装它,但它并不干净。

我建议在线程或进程级别(这将是特定于操作系统的)查看处理器亲和性。如果您可以将诊断处理隔离到多核机器上的 [逻辑] 处理器的有限子集,它将为您提供一种非常完善的机制来控制相对于主进程的最大执行量。这是我在尝试做类似事情时找到的最佳解决方案。

希望对您有所帮助。

【讨论】:

以上是关于提升线程:是不是可以在移动到另一个线程之前限制线程的运行时间的主要内容,如果未能解决你的问题,请参考以下文章

当前线程阻塞时,操作系统可以主动切换到另一个线程吗?如果是这样,是不是会使异步编程的价值小得多?

提升--01---线程基础知识

std::move 将 std::string 移动到另一个线程时出错

通知线程是不是可以在被通知线程等待锁定之前锁定?

是否可以将线程执行转移到另一个线程?

多线程分布式处理