Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.69/13: Рейтинг темы: голосов - 13, средняя оценка - 4.69
 Аватар для LVV
155 / 137 / 46
Регистрация: 15.02.2010
Сообщений: 750

Закрытие pipe и дочернего проесса по прошествии времени

19.01.2019, 12:34. Показов 2875. Ответов 14
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
В текущей директории имеется файл code.exe c зацикленным процессом.
Например, скомпилированнй из такого кода:
C++
1
2
3
4
5
6
7
8
9
#include <iostream>
int main()
{
   int a,b;
   std::cin >> a >> b;
   std::cout << a + b;  
   while(true);
   return 0;
}
Требуется запустить code.exe в качестве дочернего процесса, перехватить стандартные потоки ввода/вывода и "убить" этот процесс по прошествии определённого времени.

Запущенный дочерний процесс закрыть через 2 секунды легко:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
#include <windows.h>
int main()
{
    STARTUPINFO cif;
    ZeroMemory(&cif, sizeof(STARTUPINFO));
    PROCESS_INFORMATION pi;
    CreateProcess(L"code.exe", NULL, NULL, NULL, FALSE, CREATE_NEW_CONSOLE, NULL, NULL, &cif, &pi);//запускаем процесс
    
    WaitForSingleObject(pi.hProcess, 2000);//ждём окончания дочернего процесса 2 секунды.
    TerminateProcess(pi.hProcess, 0);//убиваем процесс
    
    return 0;
}

Но как закрыть процесс, обменивающийся данными через pipe?
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
#include <windows.h>
#include <iostream>
using namespace std;
int main()
{
    setlocale(0, "");
    SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX);
    STARTUPINFO si; PROCESS_INFORMATION pi; SECURITY_ATTRIBUTES sa;
    //дескрипторы пайпов
    HANDLE newstdin, newstdout, read_stdout, write_stdin;
    //атрибуты защиты канала
    sa.lpSecurityDescriptor = NULL; sa.nLength = sizeof(SECURITY_ATTRIBUTES); sa.bInheritHandle = true;
    //создаем анонимные каналы
    CreatePipe(&newstdin, &write_stdin, &sa, 0);
    CreatePipe(&read_stdout, &newstdout, &sa, 0);
    //startupinfo для дочернего процесса
    GetStartupInfo(&si);
    si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
    si.wShowWindow = SW_SHOW;
    si.hStdOutput = newstdout;
    si.hStdError = newstdout;
    si.hStdInput = newstdin;
 
 
    //создаем дочерний процесс 
CreateProcess(L"code.exe", NULL, NULL, NULL, TRUE, CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi);
 
    char buf[] = "1 2"; //буфер данных, передаваемых дочернему процессу
    unsigned long bread;
WriteFile(write_stdin, buf, 100, &bread, NULL);//передаём из буфера данные в стандартный поток дочернего процесса
    cout << "Дано: " << buf << endl;
    CloseHandle(write_stdin);
    
    memset(buf, 0, sizeof(buf));//обнуляем буфер ввода-вывода
ReadFile(read_stdout, buf, 100, &bread, NULL);//принимаем в буфер данные из стандартного потока дочернего процесса
    cout << "Результат: " << buf << endl;
    CloseHandle(read_stdout);
    
WaitForSingleObject(pi.hProcess, 2000);//ждём окончания дочернего процесса 2 секунды.
TerminateProcess(pi.hProcess, 0);//закрываем дочерний процесс
 
    //уборка за собой
    CloseHandle(pi.hThread);
    CloseHandle(pi.hProcess);
    CloseHandle(newstdin);
    CloseHandle(newstdout);
return 0;
}
Код рабочий. Незацикленный дочерний процесс принимает и выводит данные через pipe нормально.
Но зацикленный процесс code.exe здесь не закрывается, pipe мешают.
Как закрыть pipe и дочерний процесс по прошестви определённого времени?
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
19.01.2019, 12:34
Ответы с готовыми решениями:

Автоматическое закрытие MessageBox по прошествии определенного времени
DialogResult res = MessageBox.Show(&quot;Вы хотите позвонить в скорую помощь?!&quot;, &quot;Выбор&quot;, MessageBoxButtons.YesNo); if (res ==...

Действие по прошествии определенного времени
Задача: отправить электронное письмо по прошествии 3 дней после определенного действия (есть отметка в бд и дата). Что приходит на ум мне...

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

14
1394 / 1023 / 325
Регистрация: 28.07.2012
Сообщений: 2,813
19.01.2019, 13:11
LVV, можно сначала дождаться завершения процесса, а потом уже пытаться что-либо прочитать из пайпа.
1
 Аватар для LVV
155 / 137 / 46
Регистрация: 15.02.2010
Сообщений: 750
19.01.2019, 14:35  [ТС]
Цитата Сообщение от nonedark2008 Посмотреть сообщение
можно сначала дождаться завершения процесса
Не понял совет.
Как Вы дождётесь завершения такого дочернего процесса?
C++
1
2
3
4
5
6
7
8
9
#include <iostream>
int main()
{
   int a,b;
   std::cin >> a >> b;
   std::cout << a + b;  
   while(true);
   return 0;
}
Если же Вы имеете ввиду, что нужно в другом месте родительского кода ставить WaitForSingleObject, то где именно?
Никакие варианты не работают:
C++
1
2
3
4
5
CreateProcess...
WaitForSingleObject...
WriteFile...
ReadFile...
TerminateProcess...
C++
1
2
3
4
5
CreateProcess...
WriteFile...
ReadFile...
WaitForSingleObject...
TerminateProcess...
Дочерний зацикленный процесс не закрывается.
0
1394 / 1023 / 325
Регистрация: 28.07.2012
Сообщений: 2,813
19.01.2019, 14:43
Цитата Сообщение от LVV Посмотреть сообщение
Как Вы дождётесь завершения такого дочернего процесса?
Ждем завершения процесса N секунд, если завершился - читаем из пайпа, не завершился - принудительно завершаем и выходим.
1
 Аватар для LVV
155 / 137 / 46
Регистрация: 15.02.2010
Сообщений: 750
19.01.2019, 15:11  [ТС]
Спасибо, nonedark2008, но как это реализовать?
Вот так не получается:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
CreateProcess...
    WaitForSingleObject(pi.hProcess, 2000);//ждём окончания дочернего процесса 2 секунды.
    DWORD info = 0;//переменная для хранения кода процесса
    GetExitCodeProcess(pi.hProcess, &info); //определяем код состояния дочернего процесса
    
     if (!info)//если процесс завершен
    {
        WriteFile...
        CloseHandle...
 
        ReadFile...
        CloseHandle...
 
        //уборка за собой
        CloseHandle...
        CloseHandle...
    }
    else
    {
        ExitProcess(info);//выходим из дочернего процесса
        TerminateProcess(pi.hProcess, 0);//убиваем процесс
    }
Дочерний процесс по-прежнему не закрывается и потоки из pipe не читаются...

Добавлено через 3 минуты
Когда дочерний процесс закрываю вручную (закрытие дочернего окна), то данные из pipe выводятся как и положено.

Добавлено через 5 минут
И так не работает:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
CreateProcess...
    
        WriteFile...
        CloseHandle...
 
WaitForSingleObject(pi.hProcess, 2000);
    DWORD info;
    GetExitCodeProcess(pi.hProcess, &info); 
    if (!info)//если процесс завершен
    {        
     ReadFile...
        CloseHandle...
     }
    else
    {
        ExitProcess(info);
        TerminateProcess(pi.hProcess, 0);
    }
 
//уборка за собой
        CloseHandle...
        CloseHandle...
0
1394 / 1023 / 325
Регистрация: 28.07.2012
Сообщений: 2,813
19.01.2019, 15:46
LVV, если WaitForSingleObject вернул WAIT_TIMEOUT, значит время вышло, а процесс все еще не завершился.
1
285 / 176 / 21
Регистрация: 16.02.2018
Сообщений: 666
19.01.2019, 16:01
https://stackoverflow.com/ques... ateprocess
1
 Аватар для LVV
155 / 137 / 46
Регистрация: 15.02.2010
Сообщений: 750
19.01.2019, 16:41  [ТС]
Цитата Сообщение от nonedark2008 Посмотреть сообщение
если WaitForSingleObject вернул WAIT_TIMEOUT, значит время вышло, а процесс все еще не завершился.
Ну, и что это нам даёт, кроме того, что в условии можно использовать WaitForSingleObject?
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
#include <windows.h>
#include <iostream>
using namespace std;
 
int main()
{
    setlocale(0, "");
    SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX);
    STARTUPINFO si; PROCESS_INFORMATION pi; SECURITY_ATTRIBUTES sa;
    //дескрипторы пайпов
    HANDLE newstdin, newstdout, read_stdout, write_stdin;
    //атрибуты защиты канала
    sa.lpSecurityDescriptor = NULL; sa.nLength = sizeof(SECURITY_ATTRIBUTES); sa.bInheritHandle = true;
    //создаем анонимные каналы
    CreatePipe(&newstdin, &write_stdin, &sa, 0);
    CreatePipe(&read_stdout, &newstdout, &sa, 0);
    //startupinfo для дочернего процесса
    GetStartupInfo(&si);
    si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
    si.wShowWindow = SW_SHOW;
    si.hStdOutput = newstdout;
    si.hStdError = newstdout;
    si.hStdInput = newstdin;
    
//создаем дочерний процесс 
CreateProcess(L"code.exe", NULL, NULL, NULL, TRUE, CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi);
        char buf[] = "1 2"; //буфер данных, передаваемых дочернему процессу
        unsigned long bread;
WriteFile(write_stdin, buf, 100, &bread, NULL);//передаём из буфера данные в стандартный поток дочернего процесса
        cout << "Дано: " << buf << endl;
CloseHandle(write_stdin);
        
if (!WaitForSingleObject(pi.hProcess, 2000))//если процесс завершен
    {
        memset(buf, 0, sizeof(buf));//обнуляем буфер ввода-вывода
ReadFile(read_stdout, buf, 100, &bread, NULL);//принимаем в буфер данные из стандартного потока дочернего процесса
        cout << "Результат: " << buf << endl;
        CloseHandle(read_stdout);
    }
else
    {
        DWORD info;
        GetExitCodeProcess(pi.hProcess, &info);
    ExitProcess(info);//выходим из дочернего процесса
        TerminateProcess(pi.hProcess, 0);//убиваем процесс
    }
 
//уборка за собой
        CloseHandle(pi.hThread);
        CloseHandle(pi.hProcess);
        CloseHandle(newstdin);
        CloseHandle(newstdout);
    return 0;
}
Время вышло. Зацикленный дочерний процесс не завершился. Но я не могу прочитать данные из pipe и не могу закрыть дочерний процесс!

Для незацикленного процесса приведенный код по-прежнему работает нормально.
0
285 / 176 / 21
Регистрация: 16.02.2018
Сообщений: 666
19.01.2019, 16:51
Цитата Сообщение от LVV Посмотреть сообщение
Но я не могу прочитать данные из pipe
Потому что они в буфере зацикленного процесса.
1
 Аватар для LVV
155 / 137 / 46
Регистрация: 15.02.2010
Сообщений: 750
19.01.2019, 16:52  [ТС]
Цитата Сообщение от rat0r Посмотреть сообщение
https://stackoverflow.com/questions/...-createprocess
Ну, это ответ вопросом на вопрос...
0
285 / 176 / 21
Регистрация: 16.02.2018
Сообщений: 666
19.01.2019, 16:53
Цитата Сообщение от LVV Посмотреть сообщение
Ну, это ответ вопросом на вопрос
Вы антисемит?
0
1394 / 1023 / 325
Регистрация: 28.07.2012
Сообщений: 2,813
19.01.2019, 16:55
Цитата Сообщение от LVV Посмотреть сообщение
Зацикленный дочерний процесс не завершился. Но я не могу прочитать данные из pipe и не могу закрыть дочерний процесс!
А что тебе от этого зависшего процесса нужно?
Цитата Сообщение от LVV Посмотреть сообщение
ExitProcess(info);//выходим из дочернего процесса
Так ты только свой процесс прибьешь.

Если время вышло, то бы должен 1) прибить дочерний процесс 2) если надо, прочитать остатки данных из пайпа
1
 Аватар для LVV
155 / 137 / 46
Регистрация: 15.02.2010
Сообщений: 750
19.01.2019, 17:40  [ТС]
Цитата Сообщение от rat0r Посмотреть сообщение
Потому что они в буфере зацикленного процесса.
Но когда я останавливаю дочерний процесс вручную (закрываю дочернее окно), родительский - получает данные из pipe!!!
Почему же нельзя программно закрыть дочерний процесс, чтобы высвободить буфер с данными pipe?

Добавлено через 15 минут
Цитата Сообщение от nonedark2008 Посмотреть сообщение
ExitProcess(info);
Так ты только свой процесс прибьешь.
Почему?
Я же запускаю дочерний процесс:
C++
1
CreateProcess(L"code.exe", NULL, NULL, NULL, TRUE, CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi);
затем определяю его код:
C++
1
GetExitCodeProcess(pi.hProcess, &info);
и потом закрываю и/или убиваю дочерний процесс:
C++
1
2
ExitProcess(info);
TerminateProcess(pi.hProcess, 0);
Цитата Сообщение от nonedark2008 Посмотреть сообщение
А что тебе от этого зависшего процесса нужно?
Мне нужно его просто закрыть или убить через установленное время. Тут даже данные из пайпов можно не читать (хотя неплохо было бы их сохранить), главное - остановить зацикленный дочерний процесс при обмене данными с родительским через pipe!!!

Добавлено через 5 минут
Но в то же время нормальный, не зацикленный дочерний процесс должен нормально обмениваться данными через pipe (что и происходит)

Добавлено через 11 минут
Цитата Сообщение от nonedark2008 Посмотреть сообщение
ты должен 1) прибить дочерний процесс 2)сесли надо, прочитать остатки данных из пайпа
Вот я и спрашиваю как это сделать.
0
285 / 176 / 21
Регистрация: 16.02.2018
Сообщений: 666
19.01.2019, 17:47
Цитата Сообщение от LVV Посмотреть сообщение
Но когда я останавливаю дочерний процесс вручную (закрываю дочернее окно), родительский - получает данные из pipe!!!
Значит при закрытии окна происходит более graceful завершение и буферы сбрасываются каким-нибудь колбэком, добавляемым в atexit при старте.
0
 Аватар для LVV
155 / 137 / 46
Регистрация: 15.02.2010
Сообщений: 750
19.01.2019, 20:53  [ТС]
В общем, пришел к единственному выводу: либо убивать затянувшийся дочерний процесс, либо читать из pipe данные.
C++
1
2
3
4
if (WaitForSingleObject(pi.hProcess, 2000))//если процесс  не завершен
    TerminateProcess(pi.hProcess, 0);//убиваем процесс
else
      ReadFile(read_stdout, buf, 100, &bread, NULL);//читаем данные из pipe
Прочитать данные после закрытия процесса у меня не получается.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
19.01.2019, 20:53
Помогаю со студенческими работами здесь

Блокировка сеанса RDP по прошествии определенного времени
Добрый день, коллеги. Нужно настроить блокировку сеанса rdp по прошествии определенного времени. Блокироваться должно само окно как на...

Самоотключение звука, по прошествии времени, Realtek, Windows 10
Добрый день, уважаемые эксперты, просьба помочь-подсказать со следующей проблемой: периодически отключается звук, сам собой, в период...

ASP.NET MVC: Нотификации по прошествии определенного времени
Всем привет. У меня есть необходимость с определенной периодичностью при определенных условиях отправлять пользователям сайта...

По прошествии некоторого времени пропадает звук, после ребута появляется
Всем здравствуйте! Система такая &quot;компьютер - микшер - колонки&quot; и у меня такая штука происходит - по прошествии некоторого времени...

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


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
15
Ответ Создать тему
Новые блоги и статьи
Символьное дифференцирование
igorrr37 13.02.2026
/ * Логарифм записывается как: (x-2)log(x^2+2) - означает логарифм (x^2+2) по основанию (x-2). Унарный минус обозначается как ! */ #include <iostream> #include <stack> #include <cctype>. . .
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
И ясному Солнцу
zbw 12.02.2026
И ясному Солнцу, и светлой Луне. В мире покоя нет и люди не могут жить в тишине. А жить им немного лет.
«Знание-Сила»
zbw 12.02.2026
«Знание-Сила» «Время-Деньги» «Деньги -Пуля»
SDL3 для Web (WebAssembly): Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 12.02.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами и вызывать обработчики событий столкновения. . . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 11.02.2026
Содержание блога Библиотека SDL3 содержит встроенные инструменты для базовой работы с изображениями - без использования библиотеки SDL3_image. Пошагово создадим проект для загрузки изображения. . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL3_image
8Observer8 10.02.2026
Содержание блога Библиотека SDL3_image содержит инструменты для расширенной работы с изображениями. Пошагово создадим проект для загрузки изображения формата PNG с альфа-каналом (с прозрачным. . .
Установка Qt-версии Lazarus IDE в Debian Trixie Xfce
volvo 10.02.2026
В общем, достали меня глюки IDE Лазаруса, собранной с использованием набора виджетов Gtk2 (конкретно: если набирать текст в редакторе и вызвать подсказку через Ctrl+Space, то после закрытия окошка. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru