gpt4 book ai didi

c++ - 我如何在 C++ 中处理阻塞调用的并发任务?

转载 作者:塔克拉玛干 更新时间:2023-11-03 06:57:22 28 4
gpt4 key购买 nike

让这个例子变得简单。在 C++ 中,我有一个性能关键型应用程序,它对阻塞的数据库进行了大量调用。但是我在继续之前需要数据,所以我需要等待。我想让出并让另一个任务运行。

线程很昂贵,所以我牢记这一点。我的问题是因为我需要阻止我如何保持应用程序快速?感觉就像因为 API block (假设我正在使用 fopen 或 mysql 查询调用)我无法准确调用 runNextTaskWhileIWait(); 看来我还必须创建线程。

当我必须处理阻塞调用时,我可以做些什么来保持性能?

-edit- 如果忍受它并让它阻塞以便它可以开展业务,性能会更好吗?或者我可以做些什么来获得更好的性能?

最佳答案

如果正确使用线程,并且当它们是完成工作的正确工具(存在替代方案)时,线程并不昂贵。通常,线程是“昂贵的”,如果你:

  • 过于频繁地创建它们
  • 您没有正确分配工作负载(是否有太多事件线程?您的任务是否太小?它们是否都在争夺同一资源?)。
  • 并发通信过多,或者您的锁定机制粒度不是最优的。

一些注意事项:

  • 任务是否适合并行化?有些不是,有些应该做得更大。
  • 你如何创建线程?创建线程的成本相对较高,但在许多情况下,您可以通过使用线程池来避免这种情况。
  • 使用您当前的线程创建模型,您的程序可以为每个核心创建多少个线程?如果你创建太多,你不会从多线程中获益太多。
  • 您正在争夺什么资源,而多线程将在哪些方面发挥作用?在这种情况下,它可能是网络或磁盘,但您可以继续执行 cpu 和内存密集型任务。如果您需要快速执行,请确保分配得很好(尝试使用较小的线程池,这些线程池指定了它们绑定(bind)使用的资源的目标)。同样,您可能需要考虑您的任务如何从磁盘读取,以及是否可以改进。
  • 类似地,您可以将任务/资源本地化并编码到数据库,因为如果它以串行方式运行。
  • 在某些情况下,线程是错误的答案。为真正同步的任务创建线程只会减慢速度。

假设您到目前为止所做的一切都是正确的,我的第一个方法是:

  • 将所有数据库访问本地化到一个带有任务池的小型专用线程
  • 重新考虑程序的执行方式 - 如果工作量不大,则删除同步(等待)要求。

如果你曾经花时间正确地实现一个大型并发程序,它(很可能)会从根本上改变你处理并发问题和一般程序的方式。许多当今可用的高级工具/库(用于 C++)目标是现有程序的并行化。许多还针对简单和本地化的案例(例如并行化这个循环)。在流程和性能方面,已经或正在适应利用并发的程序与设计为并发执行而开发的程序之间存在很大差异。

-edit- Is the performance better if put up with it and let it block so it can do its business?

这取决于任务和频率。考虑它将如何分配。如果您通过的实现强制执行串行操作,那么一次发出 100 个请求只会减慢速度,因为您只是在创建可能需要大量资源的任务,同时增加对给定资源的竞争。它可能只会导致创建许多线程和分配,引入大量锁定,并引入大量上下文切换。

or is there something i can do to get better performance?

理想情况下,您会了解您使用的接口(interface)如何运行,并更新您的程序以优化流程以实现并发执行。这通常需要阅读相关 API 的文档以了解它们如何执行、分析、了解您现有问题的位置,并确定适合并行化的程序/问题。学习并发机制是一个步骤,实现线程安全程序是另一步,学习编写最佳的高性能并发实现并很好地实现它们可以说比其他两个加起来更难。许多开发者停留在#1 或#2。

关于c++ - 我如何在 C++ 中处理阻塞调用的并发任务?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7879908/

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