【问题标题】:future is not run even if get() is called即使调用 get(),future 也不会运行
【发布时间】:2016-04-24 20:49:35
【问题描述】:

我想并行运行一些system 调用,但即使我调用f1.get(),以下行中的处理也不会发生。这段代码有什么问题?

auto f1 = std::async( system, string("cp a b").c_str() );
f1.get(); // there is still no file "b".

注意:我之所以写string(...).c_str(),是因为在我的真实代码中,我使用的是将来自不同字符串的参数放在一起。

【问题讨论】:

  • string("cp a b").c_str() 将在运行时将一个悬空指针传递给system
  • 另一方面,字符串字面量仍然存在。 std::async( system, "cp a b")
  • 而且代码似乎有效。构造 system 的参数的方式可能存在一些问题。
  • 请不要在您的问题中输入解决方案,而是发布答案并接受它。

标签: c++ c++11 asynchronous future


【解决方案1】:

包含您的命令的std::string 是一个临时对象,并且只会在std::async 调用结束之前存在, 因此,在调用 system 时,指针可能会引用已删除的内存,这可能会发生工作,或者它可能会读取 rm -rf / --no-preserve-root - 这是未定义的行为。

您需要确保字符串对象的寿命足够长。在您的示例中,这很容易,但如果您要启动异步操作,情况并非总是如此。

C++11 lambda 表达式为我们提供了一种很好的方式来存储字符串,只要我们需要它:

std::string command = "cp main.cpp b";

auto f1 = std::async(std::launch::async, 
    [command]{ // copy command into the closure
        std::system(command.c_str()); 
    }
);

另外,请注意您没有请求 async 启动策略,因此您的函数可能仍会同步执行。

旁注:如果您正在启动外部进程并想要捕获输出、退出状态等,您可能需要考虑使用 POCO's Process 之类的东西。

【讨论】:

    猜你喜欢
    • 2023-04-04
    • 2020-06-23
    • 1970-01-01
    • 2016-09-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多