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

0

У меня есть родительский процесс, и я хотел бы запустить дочерний процесс на определенную продолжительность (например, N миллисекунды). Я делаю это в c++ (и в окнах).

Могу ли я предоставить некоторый параметр CreateProcess, который убьет его через некоторое время и вернет управление родительскому приложению? Если нет, есть ли другой способ сделать это?

Теги:
multithreading
process
createprocess

2 ответа

1
Лучший ответ

Могу ли я предоставить некоторый параметр CreateProcess...?

Да, вы можете передать желаемую duration (N) с параметром lpCommandLine в процесс, который нужно запустить.

Детский процесс может анализировать lpCommandLine и настраивать таймер с требуемой duration. Этот таймер может быть, например, Waiting Timer или просто потоком с

Sleep(duration);               // waits the duration
ExitProcess(GetLastError());   // exits the "remote" process

Нить (поток внутри дочернего процесса) завершает весь дочерний процесс после duration. Идея WaitableTimer требует частого вызова функции ожидания. Подробнее см. Использование объектов ожидающего таймера.

Но: родительский процесс будет постоянно "контролироваться". Однако: вы можете дополнительно ввести состояние ожидания в родительском процессе, используя функцию ожидания (например, WaitForSingleObject, ожидая, когда дочерний процесс обработает дескриптор, чтобы фактически спящий режим родительского процесса до тех пор, пока дочерний процесс не завершится. В верхней части вы можете оценить возвращаемое значение дочерний процесс вызовом функции GetExitCodeProcess.

Описанные схемы гарантируют, что желаемая duration лучше всего выполняется, однако вы также можете контролировать duration от родительского процесса с помощью именованного события. Подробнее см. Использование объектов событий. При таком подходе родительский процесс может установить событие, когда duration "потребляется". Детский процесс ждет этого события и завершается, когда событие было установлено. Этот подход может быть немного менее точным, так как родитель не совсем знает, когда началась детская duration.

Пример с ожидаемым таймером:

Родительский процесс:

...
#define CHILD_DURATION 2000  // 2000 ms    

HANDLE hProcess;
char ChildName[MAX_PATH];
char CommandLine[MAX_PATH];

sprintf_s(ChildName,MAX_PATH,"MyChild.exe");
sprintf_s(CommandLine,MAX_PATH,"%d",CHILD_DURATION);

// start the child 
hProcess = CreateProcess(ChildProcessName,CommandLine,....
if (0 == hProcess)
{
  // error with process creation
  printf("CreateProcessfailed (%d)\n", GetLastError());
  return GetLastError();
}

// and wait for it to finish
if (WAIT_OBJECT_0 == WaitForSingleObject(hProcess,INFINITE) 
{
  // child finished
} else
{
  // error with wait
  printf("WaitForSingleObject failed (%d)\n", GetLastError());
  return GetLastError();
}  
...

Детский процесс:

int main(int argc, char * argv[])
{

    HANDLE hWaitableTimer CreateWaitableTimer(NULL,TRUE,NULL);
    if (NULL == hWaitableTimer)
    {
        printf("CreateWaitableTimer failed (%d)\n", GetLastError());
        return GetLastError();
    }

    DWORD dwDuration = atoi(argv[1]);
    LARGE_INTEGER liDueTime = -10000 * dwDuration; 
    // waitable timer due time is in 100 nano second units
    // negative values indicate relative time
    if (!SetWaitableTimer(hTimer, &liDueTime, 0, NULL, NULL, 0))
    {
        printf("SetWaitableTimer failed (%d)\n", GetLastError());
        return GetLastError();
    }

    DWORD dwKeepGoing = TRUE;
    // enter the "to do" loop while waiting for the timer...
    While (dwKeepGoing) 
    {
        switch (WaitForSingleObject(hTimer,0) 
        {
            case WAIT_OBJECT_0:
                // duration over, 
                // optionally finalize "to do" stuff here 
                // and end child
                dwKeepGoing = FALSE;

            case WAIT_TIMEOUT:
                // do stuff here
                break;

            case WAIT_FAILED:
                // the wait function has failed                     
                printf("WaitForSingleObject failed (%d)\n", GetLastError());
                return GetLastError();
        }
     }
     return 0;
}
  • 0
    Можно ли об этом поговорить здесь: chat.stackoverflow.com/rooms/43987/child-process
  • 1
    @brainydexter: добавлен пример времени ожидания
1

Никто не убьет процесс для вас, если вы не сделаете это самостоятельно (например, из родительского процесса), или этот процесс не выйдет.

Обратите внимание, что также нет такой вещи, как "и контроль возврата к родительскому приложению". После запуска дочернего процесса как родительский, так и дочерний процессы имеют свой собственный "контроль" и выполняются одновременно, потребляя процессорное время, отдаваемое процессам операционной системой.

В общем, вы решаете, кто закончит этот процесс. Если вы делаете это из родительского процесса, то после этого вы начинаете обрабатывать дескриптор обработки и использовать (но не очень хорошо) API TerminateProcess для дочернего процесса.

В противном случае, и это лучше, сам дочерний процесс продолжает смотреть во время выполнения и просто выходит, когда придет время:

main() {
  time_to_exit = now() + N;
  while(now() < time_to_exit) {
    keep_doing_my_stuff();
  }
}
  • 0
    Мне нужно запустить дочерний процесс в течение очень определенного времени, так как я измеряю задержку для определенной операции. Похоже, из-за среза времени я не могу быть точным в этом?
  • 0
    Порождение процесса - громоздкая операция, несопоставимая с длительностью временного интервала. Если быть точным на миллисекундах, вы, скорее всего, даже не хотите порождать процессы и вместо этого переосмыслить, как вы можете сделать это по-другому.
Показать ещё 1 комментарий

Ещё вопросы

Сообщество Overcoder
Наверх
Меню