【问题标题】:Python-like multiprocessing in C++C++ 中的类 Python 多处理
【发布时间】:2016-10-13 08:50:56
【问题描述】:

我是 C++ 的新手,我来自 Python 的长期背景。

我正在寻找一种在 C++ 中并行运行函数的方法。我读了很多关于std::async 的文章,但对我来说仍然不是很清楚。

  1. 下面的代码做了一些非常有趣的事情

    #include <future>
    #include <iostream>
    
    void called_from_async() {
      std::cout << "Async call" << std::endl;
    }
    
    int main() {
      //called_from_async launched in a separate thread if possible
      std::future<void> result( std::async(called_from_async));
    
      std::cout << "Message from main." << std::endl;
    
      //ensure that called_from_async is launched synchronously
      //if it wasn't already launched
      result.get();
    
      return 0;
    }
    

    如果我多次运行它,有时输出是我所期望的:

    Message from main.
    Async call
    

    但有时我会得到这样的结果:

    MAessysnacg ec aflrlom main.
    

    为什么cout 不先发生?我清楚地在cout 之后调用.get() 方法。

  2. 关于并行运行。如果我有这样的代码:

    #include <future>
    #include <iostream>
    #include <vector>
    
    int twice(int m) {
      return 2 * m;
    }
    
    int main() {
      std::vector<std::future<int>> futures;
    
      for(int i = 0; i < 10; ++i) {
        futures.push_back (std::async(twice, i));
      }
    
      //retrive and print the value stored in the future
      for(auto &e : futures) {
        std::cout << e.get() << std::endl;
      }
    
      return 0;
    }
    

    twice 函数的所有 10 次调用将同时在不同的内核上运行?

    如果没有,C++ 中是否有类似 Python multiprocess lib 的东西?

    主要是我正在寻找的:

    我编写了一个函数,并使用 n 个输入调用它?多处理?它会同时在n个节点上运行该函数1次。

【问题讨论】:

  • 由于std::cout 是内部同步的,您的结果应该永远发生。这实际上是您看到的确切结果吗?如果是这样,那就是编译器错误。 — 另一条评论,请不要在您发布的代码中添加行号,这会使其他人更难复制粘贴来尝试代码。
  • @GáborErdős 您误解了异步期货的运作方式。当.get 被调用时它们不会被执行——get 只是确保执行已经完成,但是它们很可能会提前开始执行。否则,为什么您会期望您的第二个代码有不同的行为?毕竟,get 在你所有的期货上都被依次调用。
  • @GáborErdős 取决于执行策略……但总的来说(特别是在std::async 的情况下),是的。但是,这仍然不能解释您的乱码输出,请参阅我的第一条评论。
  • @GáborErdős 混合cerrcout 应该是这种混合文本发生的唯一方式。或者当您使用不同的输出时,但在这种情况下,您的示例将是错误的。
  • @Pod C++ 在标准库中有一个线程库(头文件&lt;thread&gt;)。 pthreads 不是标准的 C++,因此需要考虑可移植性问题。它是 C。

标签: python c++ asynchronous multiprocessing


【解决方案1】:

1) result.get(); 不启动线程。它只等待结果。并行线程通过std::async(called_from_async) 调用(或编译器决定时)启动。

但是std::cout 保证是内部线程安全的。因此,您向我们展示的结果不应该发生。有一个竞争条件,但你不能像那样混合两个输出。如果真的发生了(我怀疑),那么您可能正在处理编译器错误。

2) 您的调用将并行运行。它取决于您机器上运行的操作系统和其他进程的核心数。但是很有可能会使用所有内容(假设您可以控制整个生态系统并且没有其他 CPU 密集型进程在后台运行)。

C++ 没有类似多处理的库(至少在 std 中没有)。如果您希望运行子流程,那么有几个选项,例如分叉或popen 系统调用。

【讨论】:

  • 完美,谢谢。还有一个问题:我能否以某种方式指定我希望使用的内核数量,或者 C++ 将使用所有可用的内核?
  • @GáborErdős 这完全取决于您使用的操作系统。有些可能使您能够手动选择核心。 AFAIK 在 posix 和 windows 上都是可能的,但我不会走那条路——它很混乱,需要大量关于内核的知识。另请注意,多处理处理相同的问题。
  • 我只是问,因为我计划在 HPC 上使用脚本。如果它使用所有可用的内核对我来说是好的,只是好奇。在 python 多处理中,我可以定义一个Pool(4),它将在 4 个内核上运行。
  • @GáborErdős 不。它将运行 4 个进程,这些进程不能保证在 4 个内核上运行。正如我所说:这取决于操作系统。但是你仍然不应该担心它,这是一个微妙的。操作系统应该正确地完成它的工作。 :)
  • 哦,是的,你是对的。那么有没有办法指定处理器的数量?
猜你喜欢
  • 1970-01-01
  • 2014-08-04
  • 2017-04-12
  • 2022-01-23
  • 2016-01-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多