2014-10-21 4 views
-2

주제와 마찬가지로 C++에서 외부 프로그램을 병렬 호출 할 때 문제가 있습니다. 나는 프로그램을 호출하기 위해 system()을 사용하는 코드를 아래에 보여 주었지만 스레드 안전이 아니며 결과는 무작위이다. 어떤 실행은 다른 반환 오류이다. 스레드 안전 모드에서 병렬로 실행할 수있는 다른 가능한 방법이 있습니까? 지금은 여러 개의 시작 명령과 함께 박쥐 파일을 사용하고 모든 스레드가 출력 파일을 반환 할 때까지 기다리지 만 아주 못생긴 해결책입니다.C++에서 외부 프로그램 병렬 호출

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(); 
    } 

나는 비슷한 주제를 발견했지만 어느 것도 도움이되지 못했습니다.

이 프로그램은 Structrural stress solver 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 명령과 함께 줄을 긋습니다 - 실행할 수없는 것이고, 그런 다음 system()과 관련된 오류가 병렬로 실행됩니다. 이 특별한 실행에서는 두 개의 계산 만 성공하고 끝은 '2'입니다. Hovewer 이것은 임의적입니다. 때로는 5 회 실행됩니다. 때로는 3 회입니다. 첫 번째 라인에서 박쥐 파일을 만들면 모든 것이 정상입니다. 모든 입력에 대해 ccx.exe를 실행 한 다음 모든 스레드가 더 많은 사후 처리 출력 파일로 계산을 마칠 때까지 기다릴 것으로 예상됩니다.

+1

무슨 오류를받을 수 있나요이를 위해 당신은 람다를 사용할 수 있습니까? 당신이 "호출하는"프로그램이 thread-safe가 아닌 것은 무엇입니까? 여기에 표시된 코드는 안전하지 않을 수있는 일은 없습니다. –

+0

자세한 내용을 입력해야합니다. 어떤 종류의 오류입니까? 어떤 행동을 기대 했습니까? – dohashi

+0

[system] (http://www.cplusplus.com/reference/cstdlib/system/)의 경우 "함수가 명령에 의해 지정된 배열에 액세스합니다. null 포인터를 인수로 사용하여이 함수를 호출하는 것은 안전합니다. 그것은 시스템과 라이브러리 구현에 달려있다. " 문제가 될 수도 있습니다. – crashmstr

답변

0

표현 ("start ccx.exe Calculix_wings_" + to_string(nThread))일시적으로std::string 객체를 생성하고, 그런 다음 포인터를 얻을 수 c_str를 사용하기 때문에, thread constructor복사이 임시 객체에 대한 포인터. 생성자가 반환하면 임시 객체가 파괴되고 스레드에 매달린 포인터가 남습니다.

댕글 링 (또는 다른 방식으로 불법) 포인터를 사용하면 undefined behavior으로 연결되며 이는 사용자가보고있는 것입니다.

실제로이 문제를 직접 해결할 방법이 없으므로 std::string 개체를 인수로 사용하는 래퍼 함수를 ​​사용해야하며 대신 스레드 생성자가 임시 문자열 개체를 복사하도록해야합니다. 모든 인수를 전달할

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))); 
    })); 
+0

고마워요! 추가 c_str()와 함께 두 번째 코드를 사용했습니다. 이제 제대로 작동합니다. – curky

관련 문제