Qt 中大量同时长时间运行的操作

发布于 2024-08-16 09:49:32 字数 1140 浏览 4 评论 0原文

我有一些长期运行的操作,数量达到数百个。目前他们每个人都在自己的线程上。我使用线程的主要目标不是加快这些操作的速度。在这种情况下,更重要的是它们似乎是同时运行的。

我了解协作式多任务处理和纤维。然而,我试图避免任何需要接触操作中的代码的事情,例如用像 yieldToScheduler() 这样的东西来填充它们。我也不想规定这些例程被程式化以进行编码以发出一口大小的任务项队列......我想将它们视为黑匣子。

目前我可以忍受这些缺点:

  • 最大线程数往往是 O(1000)
  • 每个线程的成本是 O(1MB)

为了解决由于上下文切换而导致的糟糕的缓存性能,我确实有一个计时器的想法,它可以兼顾优先级,以便只有 idealThreadCount() 线程始终处于“正常”优先级,其余所有线程均设置为“空闲”。这将使我扩大时间片,这意味着更少的上下文切换,并且仍然适合我的目的。

问题#1:这是个好主意吗?一个缺点是它无法在 Linux 上运行(文档说那里没有 QThread::setPriority())。

问题#2:还有其他想法或方法吗? QtConcurrent是否考虑过这种场景?

(一些相关阅读: how-many-threads-does-it-take-to-make-them-a-bad-choice多线程或-as-few-threads-as-possible, linux中每个进程的最大线程数)

I have some long-running operations that number in the hundreds. At the moment they are each on their own thread. My main goal in using threads is not to speed these operations up. The more important thing in this case is that they appear to run simultaneously.

I'm aware of cooperative multitasking and fibers. However, I'm trying to avoid anything that would require touching the code in the operations, e.g. peppering them with things like yieldToScheduler(). I also don't want to prescribe that these routines be stylized to be coded to emit queues of bite-sized task items...I want to treat them as black boxes.

For the moment I can live with these downsides:

  • Maximum # of threads tend to be O(1000)
  • Cost per thread is O(1MB)

To address the bad cache performance due to context-switches, I did have the idea of a timer which would juggle the priorities such that only idealThreadCount() threads were ever at Normal priority, with all the rest set to Idle. This would let me widen the timeslices, which would mean fewer context switches and still be okay for my purposes.

Question #1: Is that a good idea at all? One certain downside is it won't work on Linux (docs say no QThread::setPriority() there).

Question #2: Any other ideas or approaches? Is QtConcurrent thinking about this scenario?

(Some related reading: how-many-threads-does-it-take-to-make-them-a-bad-choice, many-threads-or-as-few-threads-as-possible, maximum-number-of-threads-per-process-in-linux)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

年华零落成诗 2024-08-23 09:49:32
  1. 恕我直言,这是一个非常糟糕的主意。如果我是你,我会非常非常努力地寻找另一种方法来做到这一点。您将两个非常糟糕的想法结合在一起:创建大量线程,并弄乱线程优先级。

  2. 您提到这些操作只需出现即可同时运行。那么为什么不尝试找到一种方法让它们看起来同时运行,而不是真正同时运行它们呢?

  1. IMHO, this is a very bad idea. If I were you, I would try really, really hard to find another way to do this. You're combining two really bad ideas: creating a truck load of threads, and messing with thread priorities.

  2. You mention that these operations only need to appear to run simultaneously. So why not try to find a way to make them appear to run simultaneously, without literally running them simultaneously?

余生共白头 2024-08-23 09:49:32

已经过去 6 个月了,所以我要结束这个了。

首先我要说的是,线程有不止一个用途。一是加速……在多核机器时代,很多人都在关注这一点。但另一个是并发性,即使从整体上看它会减慢系统速度,但它也是可取的。然而,可以使用比线程更轻量的机制来实现并发,尽管这可能会使代码复杂化。

因此,这只是必须调整程序员便利性与用户体验之间的权衡以适应目标环境的情况之一。这就是 Google 在 Chrome 中采用每个选项卡一个进程的方法在 Mosaic 时代是不明智的(即使在其他条件相同的情况下,进程隔离更可取)。如果操作系统、内存和 CPU 不能提供良好的浏览体验……他们现在就不会这样做了。

同样,当您想要并发执行独立操作时,创建大量线程可以节省您坚持自己的调度程序和 yield() 操作的麻烦。这可能是表达代码的最简洁的方式,但如果它阻碍了目标环境,那么就需要做一些不同的事情。

所以我想我会确定这样一个想法:将来当我们的硬件比现在更好时,我们可能不必担心我们创建了多少线程。但现在我将根据具体情况进行处理。即,如果我有 100 个并发任务类 A、10 个并发任务类 B、3 个并发任务类 C...那么将 A 切换到基于光纤的解决方案并为其提供一个由几个线程组成的池可能是值得的额外的并发症。

It's been 6 months, so I'm going to close this.

Firstly I'll say that threads serve more than one purpose. One is speedup...and a lot of people are focusing on that in the era of multi-core machines. But another is concurrency, which can be desirable even if it slows the system down when taken as a whole. Yet concurrency can be achieved using mechanisms more lightweight than threads, although it may complicate the code.

So this is just one of those situations where the tradeoff of programmer convenience against user experience must be tuned to fit the target environment. It's how Google's approach to a process-per-tab with Chrome would have been ill-advised in the era of Mosaic (even if process isolation was preferable with all else being equal). If the OS, memory, and CPU couldn't give a good browsing experience...they wouldn't do it that way now.

Similarly, creating a lot of threads when there are independent operations you want to be concurrent saves you the trouble of sticking in your own scheduler and yield() operations. It may be the cleanest way to express the code, but if it chokes the target environment then something different needs to be done.

So I think I'll settle on the idea that in the future when our hardware is better than it is today, we'll probably not have to worry about how many threads we make. But for now I'll take it on a case-by-case basis. i.e. If I have 100 of concurrent task class A, and 10 of concurrent task class B, and 3 of concurrent task class C... then switching A to a fiber-based solution and giving it a pool of a few threads is probably worth the extra complication.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文