程序在使用Boost.Process调用std :: future.get()进行异步后挂起

时间:2017-11-02 22:10:55

标签: c++ boost future hang boost-process

我正在创建一个异步执行多个可执行文件的程序。我的问题是,当我从 std :: future 调用 get()函数时,我的程序会挂起而没有错误。

我正在使用Boost.Process来管理进程以及其他地方的wxWidgets。

我的程序创建一个指向包含std :: future的新BProcess的指针。计时器功能稍后每隔几毫秒检查一次,以查看每个进程是否已完成。

import org.apache.commons.lang3.StringUtils;

for(String string : arrayWoord) {
    if(StringUtils.isNotBlank(string)) {
        // get toonKnop for arrayWoord
        // get letterlijnLable for arrayWoord
    }
}

编辑:这是gdb 的'where'的输出:我想弄清楚发生了什么。这对任何人都有意义吗?

class BProcess
{
public:
    BProcess();
    boost::asio::io_service ios;
    boost::process::child child_process;
    std::future<std::string> future_result;
};

void Module::Execute() //done for each process
{
    this->process_handle = new BProcess();
    this->process_handle->child_process = boost::process::child(sfilename, boost::process::std_out > this->process_handle->future_result, this->process_handle->ios);
}

void Timer::Notify()
{
    //done in loop for each Module - hangs after first module finishes
    if (!Modules[i].process_handle->child_process.running())
    {
        std::string testStr = Modules[i].process_handle->future_result.get();
    }
}

任何帮助将不胜感激。告诉我,如果我没有显示足够的代码。

1 个答案:

答案 0 :(得分:1)

我认为你可能只是忘记/忽略了运行io_service。

这是粗略的草图。

请注意,存在多个设计问题:

  • 检查running()很活泼。如果它永远不会跑,你就是敬酒。如果你之前已经获得了未来的价值,那么你就是干杯。
  • 当您以异步方式运行进程 时,为什么要轮询计时器?你可以回应完成事件。
  • Demeter法应该适用于您的类型

<强> Live On Coliru

#include <boost/process.hpp>
#include <boost/process/async.hpp>
#include <list>
#include <memory>

struct BProcess {
    BProcess(boost::asio::io_service& svc) : ios(svc) {}

    void Execute(std::string const& sfilename) {
        namespace bp = boost::process;
        child_process = bp::child(sfilename, bp::std_out > output, ios);
    }

    boost::asio::io_service& ios;
    boost::process::child child_process;
    std::future<std::string> output;
};

struct Module { 
    Module(boost::asio::io_service& svc) : ios(svc), process(new BProcess(svc)) {}

    void Execute(std::string const& sfilename) {
        process->Execute(sfilename);
    }

    bool running() const { return process->child_process.running(); }
    std::string get_output() const { return process->output.get(); }

  private:
    boost::asio::io_service& ios;
    std::unique_ptr<BProcess> process;
};

#include <iostream>

struct Timer {
    std::list<Module> Modules;

    void Notify() {
        for (auto& m : Modules) {
            if (!m.running()) {
                std::string testStr = m.get_output();
                std::cout << "Got " << testStr.size() << " bytes of output\n";
                std::cout << "---- '" << testStr << "' ---\n";
            }
        }
    }
};

int main() {
    boost::asio::io_service ios;

    Timer timer;
    timer.Modules.emplace_back(ios);
    timer.Modules.back().Execute("/usr/bin/find");

    timer.Modules.emplace_back(ios);
    timer.Modules.back().Execute("/usr/bin/gcc");

    for (auto& m : timer.Modules)
        m.Execute("/usr/bin/find");

    ios.run();
    timer.Notify();
}
相关问题