在C ++中并行调用外部程序

时间:2014-10-21 17:18:57

标签: c++ multithreading

在主题中我遇到了在C ++中并行调用外部程序的问题。我准备下面显示的代码使用system()来调用我的程序,但它不是线程安全的,结果是随机的 - 一些运行是很好的其他返回错误。有没有其他可能的方法在线程安全模式下并行运行它?现在我使用带有多个启动命令的bat文件,并在所有线程返回输出文件时等待,但这是非常难看的解决方案。

vector<thread> threadArray;

    int nThread= 0;

    // run calcs

    for (int nThread = 0; nThread < quantity; nThread++)
    {
        threadArray.push_back(thread(system, ("start ccx.exe Calculix_wings_" + to_string(nThread)).c_str()));
        threadArray.push_back(thread(system, ("start ccx.exe Calculix_fus_" + to_string(nThread)).c_str()));
        cout << ("start ccx.exe Calculix_wings_" + to_string(nThread)).c_str() << endl;
        cout << ("start ccx.exe Calculix_fus_" + to_string(nThread)).c_str() << endl;
    }

    for (auto it = threadArray.begin(); it != threadArray.end(); ++it)
    {
        it->join();
    }

我找到了一些类似的主题,但没有一个是有帮助的。

该程序是一个结构应力解算器Calculix。这是cmd输出:

start ccx.exe Calculix_wings_0
start ccx.exe Calculix_fus_0
start ccx.exe Calculix_wings_1
start ccx.exe Calculix_fus_1
start ccx.exe Calculix_wings_2
start ccx.exe Calculix_fus_2
start ccx.exe Calculix_wings_3
start ccx.exe Calculix_fus_3
start ccx.exe Calculix_wings_4
start ccx.exe Calculix_fus_4
start ccx.exe Calculix_wings_5
start ccx.exe Calculix_fus_5
'üÜ+' is not recognized as an internal or external command,
operable program or batch file.
'Čŕ+' is not recognized as an internal or external command,
operable program or batch file.
'-' is not recognized as an internal or external command,
operable program or batch file.
'c' is not recognized as an internal or external command,
operable program or batch file.
'l' is not recognized as an internal or external command,
operable program or batch file.
'o' is not recognized as an internal or external command,
operable program or batch file.
'x' is not recognized as an internal or external command,
operable program or batch file.
'îţîţîţîţîţîţîţîţîţîţîţîţîţîţîţîţîţîţîţîţîţîţîţîţîţîţîţîţîţîţîţîţîţîţîţîţîţîţîţî
ţîţîţîţîţîţîţîţîţîţîţîţîţîţîţîţîţîţîţîţîţîţîţîţîţîţîţîţîţîţîţîţîţîţîţîţîţîţîţîţî
ţîţîţîţîţîţîţîţîţ' is not recognized as an internal or external command,
operable program or batch file.
'-' is not recognized as an internal or external command,
operable program or batch file.
'l' is not recognized as an internal or external command,
operable program or batch file.

您可以在输出中看到线程安全问题。在开始时,使用start命令行 - 不是exetutable,然后是并行运行的与system()相关的错误。在这个特定的运行中,只有两个计算成功完成,最后为'2'。 Hovewer这是随机的,有时5次运行完成,有时3次。当我从第一行创建一个bat文件时一切正常。我期望为每个输入运行ccx.exe,然后等到所有线程完成计算以进一步后处理输出文件。

1 个答案:

答案 0 :(得分:0)

表达式("start ccx.exe Calculix_wings_" + to_string(nThread))创建一个临时 std::string对象,然后您使用c_str获取指针,thread constructor仅< em> copies 指向此临时对象的指针。构造函数返回后,临时对象被破坏,线程留下一个悬空指针。

使用悬挂(或其他非法)指针会导致undefined behavior,这就是您所看到的。

实际上没有办法直接解决这个问题,你必须使用一个以std::string对象作为参数的包装函数,让线程构造函数复制临时字符串对象。为此,您可以使用lambda:

threadArray.push_back(thread(
    [](const std::string arg) { system(arg.c_str()); },
    ("start ccx.exe Calculix_wings_" + to_string(nThread))));

或者根本不传递论据:

threadArray.push_back(thread(
    [nThread]()
    {
        system(("start ccx.exe Calculix_wings_" + to_string(nThread)));
    }));