Как узнать, запущен ли дочерний процесс?

Я порождаю процесс в моем приложении:

int status = posix_spawnp(&m_iProcessHandle, (char*)strProgramFilepath.c_str(), NULL, NULL, argsWrapper.m_pBuffer, NULL);

Когда я хочу посмотреть, запущен ли процесс, я использую kill:

int iReturn = kill(m_iProcessHandle,0);

Но после того, как порожденный процесс закончил свою работу, он зависает. Возвращаемое значение в команде kill всегда равно 0. Не -1. Я вызываю kill из кода, но если я вызываю его из командной строки, ошибки нет — порожденный процесс все еще существует.

Только когда мое приложение завершает работу, команда kill командной строки возвращает «Нет такого процесса».

Я могу изменить это поведение в моем коде с помощью этого:

int iResult = waitpid(m_iProcessHandle, &iStatus, 0);

Вызов waitpd закрывает порожденный процесс, и я могу вызвать kill и получить -1 обратно, но к тому времени я знаю, что порожденный процесс мертв.

И waitpd блокирует мое приложение!

Как я могу протестировать порожденные процессы, чтобы увидеть, запущен ли он, но не блокируя мое приложение?

ОБНОВИТЬ

Спасибо за помощь! Я выполнил ваш совет и вот результат:

// background-task.cpp
//

#include <spawn.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <signal.h>

#include "background-task.h"

CBackgroundTask::CBackgroundTask()
{

// Initialize member variables
m_iProcessHandle = 0;

}

CBackgroundTask::~CBackgroundTask()
{

// Clean up (kill first)
_lowLevel_cleanup(true);

}

bool CBackgroundTask::IsRunning()
{

// Shortcuts
if (m_iProcessHandle == 0)
return false;

// Wait for the process to finish
int iStatus = 0;
int iResult = waitpid(m_iProcessHandle, &iStatus, WNOHANG);
return (iResult != -1);

}

void CBackgroundTask::Wait()
{

// Wait (clean up without killing)
_lowLevel_cleanup(false);

}

void CBackgroundTask::Stop()
{

// Stop (kill and clean up)
_lowLevel_cleanup(true);

}

void CBackgroundTask::_start(const string& strProgramFilepath, const string& strArgs, int iNice /*=0*/)
{

// Call pre-start
_preStart();

// Split the args and build array of char-strings
CCharStringAarray argsWrapper(strArgs,' ');

// Run the command
int status = posix_spawnp(&m_iProcessHandle, (char*)strProgramFilepath.c_str(), NULL, NULL, argsWrapper.m_pBuffer, NULL);
if (status == 0)
{

// Process created
cout << "posix_spawn process=" << m_iProcessHandle << "  status=" <<     status << endl;

}
else
{

// Failed
cout << "posix_spawn: error=" << status << endl;

}

// If process created...
if(m_iProcessHandle != 0)
{

// If need to adjust nice...
if (iNice != 0)
{

// Change the nice
stringstream ss;
ss << "sudo renice -n " << iNice << " -p " << m_iProcessHandle;
_runCommand(ss.str());

}

}
else
{

// Call post-stop success=false
_postStop(false);

}

}

void CBackgroundTask::_runCommand(const string& strCommand)
{

// Diagnostics
cout << "Running command: " << COUT_GREEN << strCommand << endl << COUT_RESET;

// Run command
system(strCommand.c_str());

}

void CBackgroundTask::_lowLevel_cleanup(bool bKill)
{

// Shortcuts
if (m_iProcessHandle == 0)
return;

// Diagnostics
cout << "Cleaning up process " << m_iProcessHandle << endl;

// If killing...
if (bKill)
{

// Kill the process
kill(m_iProcessHandle, SIGKILL);

}

// Diagnostics
cout << "Waiting for process " << m_iProcessHandle << " to finish" << endl;

// Wait for the process to finish
int iStatus = 0;
int iResult = waitpid(m_iProcessHandle, &iStatus, 0);

// Diagnostics
cout << "waitpid: status=" << iStatus << "   result=" << iResult << endl;

// Reset the process-handle
m_iProcessHandle = 0;

// Call post-stop with success
_postStop(true);

// Diagnostics
cout << "Process cleaned" << endl;

}

0

Решение

Пока родительский процесс не вызывает один из wait() функции, чтобы получить статус выхода ребенка, ребенок остается как процесс зомби. Если вы бежите ps в течение этого времени вы увидите, что процесс все еще существует в Z государство. Так kill() возвращается 0 потому что процесс существует.

Если вам не нужно получать статус ребенка, см. Как я могу предотвратить дочерние процессы зомби? за то, как вы можете заставить ребенка исчезнуть сразу после его выхода.

3

Другие решения


По вопросам рекламы [email protected]