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

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

19.01.2019, 12:34. Показов 2842. Ответов 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
Ответ Создать тему
Новые блоги и статьи
Thinkpad X220 Tablet — это лучший бюджетный ноутбук для учёбы, точка.
Programma_Boinc 23.12.2025
Thinkpad X220 Tablet — это лучший бюджетный ноутбук для учёбы, точка. Рецензия / Мнение Это мой обзор планшета X220 с точки зрения школьника. Недавно я решила попытаться уменьшить свой. . .
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Как объединить две одинаковые БД Access с разными данными
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru