0

好的,作为我的 Lib 的一部分,我需要一个“工人”应用程序来运行外部程序。通常我会打电话给:

system("");

但是这次需要的是:

  • 该程序的返回码
  • 应用程序在执行的程序运行时工作

所以一个伪代码在完美的实现中看起来像这样:

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

   ExecuteTask(m_strBinaryName);

   while(Task_Executing)
   {
     HeartBeat();
   }

   return m_iReturnCode;
}

澄清一下,我在Unix平台上运行它。

我在这里有什么选择, popen / fork ?任何有一个好的解决方案已经在运行并且可以对此有所了解的人吗?

感谢您对此的任何意见。

4

3 回答 3

1

您可以使用 fork()(如果需要线程,则使用 clone())创建一个 fork,然后在一个进程中使用 execve() 或 system() 运行程序,并在另一个进程中继续运行原始程序。

对于返回码,您甚至可以从system()call as 获取返回码:

ret = system("<your_command>");
printf("%d\n", WEXITSTATUS(ret));
于 2013-11-04T12:11:51.093 回答
1

我正在使用 linux 系统,用于线程的 boost 和用于执行命令并获得其结果的管道(如果你不知道boost,你当然应该看看它)。

我在 stackoverflow 上找到了使用管道的提示,但很抱歉我不再知道确切的问题。

我不添加外线程代码。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;
}
于 2013-11-04T13:20:48.513 回答
0

必须有某种进程间或线程间通信。如果您不想分叉或使用线程,您可以尝试使用共享文件。打开要写入子任务的文件(由 调用system()),完成后,写入一些值(例如“完成”)并关闭文件。在父任务中,心跳直到您从共享文件中读取“完成”。

您也可以通过编写全局变量而不是共享文件来做到这一点。

但是,我会对其进行强化或线程化,使用共享文件或全局变量容易出错,我不完全确定它会以这种方式工作。

于 2013-11-04T12:16:02.570 回答