2013-11-04 80 views
0

好了,因爲我的庫的一部分,我需要一個「工人」應用程序來運行外部程序。 通常我會用一個調用做到這一點:CPP運行外部程序,等待它完成並返回RETCODE

system(""); 

但此時需要的是:

該程序的
  • 返回代碼
  • 應用到執行程序運行
  • 工作一段時間

因此,僞代碼在完美實現中看起來像這樣:

CTask::Run() 
{ 
    m_iReturnCode = -1; 

    ExecuteTask(m_strBinaryName); 

    while(Task_Executing) 
    { 
    HeartBeat(); 
    } 

    return m_iReturnCode; 
} 

只是爲了澄清,我在Unix平臺上運行這個。

什麼是我選擇這裏,POPEN /叉? 任何人已經有一個很好的解決方案已經運行,可以擺脫這個請點亮一下?

感謝您的任何意見。

+0

您可能想要將它分叉或在單獨的線程中運行任務。 –

+0

我正在考慮這一點,將等待更多的建議,看看還有什麼可以在這裏做。謝謝 – PeeS

回答

1

我正在使用linux系統,提升線程和管道來執行命令並得到它的結果(如果你不知道boost你當然應該看看它)。

我發現提示計算器上這裏使用管道,但我很抱歉,我不知道確切的問題了。

我不添加外部線程代碼。只需在其自己的線程內啓動方法execute即可。

std::string execute() 
{ 
std::string result; 

// DO NOT INTERRUPT THREAD WHILE READING FROM PIPE 
boost::this_thread::disable_interruption di; 

// add echo of exit code to command to get the exit code 
std::string command = mp_command + "; echo $?"; 

// open pipe, execute command and read input from pipe 
FILE* pipe = popen(command.c_str(), "r"); 
if (pipe) 
{ 
    char buffer[128]; 
    while (!feof(pipe)) 
    { 
     if (fgets(buffer, 128, pipe) != NULL) 
     { 
      std::string currBuffer(buffer); 
      result += currBuffer; 
     } 
    } 
} 
else 
{ 
    mp_isValid = false; 
} 

// sleeping busy wait for the pipe to close 
while (pclose(pipe) == -1) 
{ 
    boost::this_thread::sleep(boost::posix_time::milliseconds(100)); 
} 

return result; 
} 
+0

現在,這聽起來像一個計劃! 完美! – PeeS

+0

只看起來像$ nix,Windows呢? – Damian

1

您可以創建fork()的(或克隆(),如果你想線程)叉子,然後在一個過程中使用的execve()或系統()運行程序,並繼續在其他正在運行的原始程序。

ret = system("<your_command>"); 
printf("%d\n", WEXITSTATUS(ret)); 
+0

好吧,它沒有按預期工作, 檢查你自己。 – PeeS

0

必須有某種形式的進程間或間通信的:

對於返回代碼,您甚至可以從system()呼叫作爲獲取返回代碼。如果您不想分叉或使用線程,則可以嘗試使用共享文件。打開要寫入子任務的文件(由system()調用),完成後寫入一些值(例如「完成」)並關閉文件。在父任務中,直到您從共享文件中讀取「完成」爲止的心跳。

您可以通過編寫一個全局變量,而不是共享的文件也做到這一點。

不過,我的堡壘或線程它,使用一個共享文件或全局變量是容易出錯的,我不能完全肯定它會工作的方式。