|
Как закрыть handle переданный процессу в порядке наследования?
|
|||
---|---|---|---|
#18+
Здравствуйте, уважаемые форумчане, не могу понять как закрыть handle, который был передан процессу в порядке наследования. (файл открывается на запись для записи консольного вывода). Точнее handle этот я закрываю, но не помогает, видимо из-за наследования и передачи другому процессу. Я как положено открываю файл, создаю процесс с передачей туда handle открытого файла. Делаю так допустим 2 раза. Потом я корректно завершаю один процесс (отправляю ему CTRL+BREAK программно). После чего если попробовать снова выполнить ту же функцию по открытию файла и созданию процесса, то пишет " Процесс не может получить доступ к файлу, так как этот файл занят другим процессом ". Я проверил утилитой handles от SysInternals и получается, что осиротевший handle открытого файла после закрытия процесса каким-то образом остаётся висеть но уже привязанный ко второму открытому консольному процессу (который я не закрывал). Как только второй процесс закрываю - все handle освобождаются. Если в коде прописать fmShareDenyNone это решает проблему, но это же не выход, а костылище. Второй процесс запускался с совершенно другим открытым на запись файлом для записи консольного вывода и c другой командой, это чтобы вы не подумали что я запускаю два процесса передавая им одинаковый хендл. Что происходит и как это побороть? Мозговой штурм устраивал, но так и не смог ничего предположить что это может быть. А теперь собственно код: Код: pascal 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.
Завершаю процесс стандартно: Код: pascal 1. 2. 3. 4.
Почему не освобождаются хэндлы - для меня загадка. Прошу помощи у гуру, заранее спасибо. ... |
|||
:
Нравится:
Не нравится:
|
|||
21.10.2021, 15:10 |
|
Как закрыть handle переданный процессу в порядке наследования?
|
|||
---|---|---|---|
#18+
У тебя usage count у handle = 3. Один - у тебя, второй - у первого запущенного процесса, третий - у второго запущенного процесса. Соответственно, файл будет закрыт когда все три его отпустят. Сделают они это через CloseHandle или выйдут из процесса - не суть важно. bInheritHandle = False поставь второму запускаемому процессу, тогда usage count будет равен 2: один у тебя и один у первого запускаемого процесса (с bInheritHandle = True). ... |
|||
:
Нравится:
Не нравится:
|
|||
21.10.2021, 15:37 |
|
Как закрыть handle переданный процессу в порядке наследования?
|
|||
---|---|---|---|
#18+
Павел ВоробьевЯ как положено открываю файл, создаю процесс с передачей туда handle открытого файла. Делаю так допустим 2 раза. То есть ты собственными руками передаёшь этот файл двум наследникам. Чему же удивляешься?.. Наследникам передаются все открытые хэндлы, а не только те о которых ты думаешь. И нет, в твоём коде хэндл не закрывается сразу после запуска дочернего процесса. Posted via ActualForum NNTP Server 1.5 ... |
|||
:
Нравится:
Не нравится:
|
|||
21.10.2021, 15:40 |
|
Как закрыть handle переданный процессу в порядке наследования?
|
|||
---|---|---|---|
#18+
GunSmoker У тебя usage count у handle = 3. Один - у тебя, второй - у первого запущенного процесса, третий - у второго запущенного процесса. Соответственно, файл будет закрыт когда все три его отпустят. Сделают они это через CloseHandle или выйдут из процесса - не суть важно. bInheritHandle = False поставь второму запускаемому процессу, тогда usage count будет равен 2: один у тебя и один у первого запускаемого процесса (с bInheritHandle = True). Я же написал, что второй процесс запускается с другими параметрами и совершенно другим файлом и к первому отношения не имеет. ... |
|||
:
Нравится:
Не нравится:
|
|||
21.10.2021, 15:40 |
|
Как закрыть handle переданный процессу в порядке наследования?
|
|||
---|---|---|---|
#18+
Dimitry Sibiryakov Павел ВоробьевЯ как положено открываю файл, создаю процесс с передачей туда handle открытого файла. Делаю так допустим 2 раза. То есть ты собственными руками передаёшь этот файл двум наследникам. Чему же удивляешься?.. Наследникам передаются все открытые хэндлы, а не только те о которых ты думаешь. И нет, в твоём коде хэндл не закрывается сразу после запуска дочернего процесса. Читайте пожалуйста внимательнее, ничего и никуда я не передаю. Каждому процессу открывается отдельный файл с отдельным хендлом, я говорю что лишь 2 раза функцию вызываю. Если проще - то первый процесс cmd.exe пишет вывод в file.log, второй процесс cmd.exe пишет в log2.log ... |
|||
:
Нравится:
Не нравится:
|
|||
21.10.2021, 15:41 |
|
Как закрыть handle переданный процессу в порядке наследования?
|
|||
---|---|---|---|
#18+
Если второму процессу сделать bInheritHandle = False нельзя, то есть и другие варианты . Вариант 1. Просто закрыть хэндл ДО запуска второго процесса. Тогда он не будет в него наследоваться, потому что не будет существовать. Вариант 2. Запустить первый процесс и сделать у себя DuplicateHandle, указав bInheritHandle = False. Закрыть первый (наследуемый) хэндл и запустить второй процесс. Хэндл не будет наследоваться, потому что будет ненаследуемым. Вариант 3. Использовать StartupInfoEx : STARTUPINFOEXBy default, passing TRUE as the value of the bInheritHandles parameter causes all inheritable handles to be inherited by the new process. This can be problematic for applications which create processes from multiple threads simultaneously yet desire each process to inherit different handles. Applications can use the UpdateProcThreadAttributeList function with the PROC_THREAD_ATTRIBUTE_HANDLE_LIST parameter to provide a list of handles to be inherited by a particular process. ... |
|||
:
Нравится:
Не нравится:
|
|||
21.10.2021, 15:45 |
|
Как закрыть handle переданный процессу в порядке наследования?
|
|||
---|---|---|---|
#18+
Павел Воробьев Я же написал, что второй процесс запускается с другими параметрами и совершенно другим файлом и к первому отношения не имеет. У тебя хэндл первого файла открыт в момент запуска второго процесса? Ты говоришь, что да: Павел Воробьев осиротевший handle открытого файла после закрытия процесса каким-то образом остаётся висеть но уже привязанный ко второму открытому консольному процессу (который я не закрывал). Поэтому нам непонятно, что тебе непонятно. ... |
|||
:
Нравится:
Не нравится:
|
|||
21.10.2021, 15:48 |
|
Как закрыть handle переданный процессу в порядке наследования?
|
|||
---|---|---|---|
#18+
GunSmoker Павел Воробьев Я же написал, что второй процесс запускается с другими параметрами и совершенно другим файлом и к первому отношения не имеет. У тебя хэндл первого файла открыт в момент запуска второго процесса? Ты говоришь, что да: Павел Воробьев осиротевший handle открытого файла после закрытия процесса каким-то образом остаётся висеть но уже привязанный ко второму открытому консольному процессу (который я не закрывал). Поэтому нам непонятно, что тебе непонятно. Процессы совершенно разные и запускаются с разными файлами, функции выполняются в отдельных потоках и друг о друге они вообще ничего не знают. Первый процесс cmd.exe пишет вывод в file.log, второй процесс cmd.exe пишет в log2.log Корректно закрываю первый процесс, файл не освобождается и какого-то лешего прилипает ко второму процессу. Если запустить 10 разных процессов с разными файлами, то они будут прилипать к оставшемуся и все файлы освободятся как только закрою последний процесс. Почему так и что делать, как сделать чтобы файл после закрытия процесса освобождался? Вот что мне не понятно))) ... |
|||
:
Нравится:
Не нравится:
|
|||
21.10.2021, 15:51 |
|
Как закрыть handle переданный процессу в порядке наследования?
|
|||
---|---|---|---|
#18+
Павел ВоробьевЧитайте пожалуйста внимательнее, ничего и никуда я не передаю. Короче, убирай из функции SetHandleInformation и bInherited. И будет тебе счастье. Posted via ActualForum NNTP Server 1.5 ... |
|||
:
Нравится:
Не нравится:
|
|||
21.10.2021, 15:53 |
|
Как закрыть handle переданный процессу в порядке наследования?
|
|||
---|---|---|---|
#18+
Dimitry Sibiryakov Павел ВоробьевЧитайте пожалуйста внимательнее, ничего и никуда я не передаю. Короче, убирай из функции SetHandleInformation и bInherited. И будет тебе счастье. С чего бы мне это делать. Это нужно, чтобы запускаемый процесс мог писать в открытый для него файл. Консольный вывод записывается в файл. Если убрать, поток ничего никуда писать не будет, херню советуете. ... |
|||
:
Нравится:
Не нравится:
|
|||
21.10.2021, 15:55 |
|
Как закрыть handle переданный процессу в порядке наследования?
|
|||
---|---|---|---|
#18+
Павел ВоробьевПочему так и что делать, как сделать чтобы файл после закрытия процесса освобождался? ProcessMonitor в руки и смотри в какой момент у тебя закрывается файл. Очевидно, что ты его закрываешь слишком поздно. Павел ВоробьевС чего бы мне это делать. С документации: https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/ns-processthreadsapi-startupinfoa Но таки да, bInheritHandles убирать не нужно. Posted via ActualForum NNTP Server 1.5 ... |
|||
:
Нравится:
Не нравится:
|
|||
21.10.2021, 15:58 |
|
Как закрыть handle переданный процессу в порядке наследования?
|
|||
---|---|---|---|
#18+
Dimitry Sibiryakov Павел ВоробьевПочему так и что делать, как сделать чтобы файл после закрытия процесса освобождался? ProcessMonitor в руки и смотри в какой момент у тебя закрывается файл. Очевидно, что ты его закрываешь слишком поздно. Павел ВоробьевС чего бы мне это делать. С документации: https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/ns-processthreadsapi-startupinfoa Но таки да, bInheritHandles убирать не нужно. Спасибо огромное, поставил FreeAndNil(conout); сразу после CreateProcess и всё нормализовалось! Респект ))) ... |
|||
:
Нравится:
Не нравится:
|
|||
21.10.2021, 16:02 |
|
Как закрыть handle переданный процессу в порядке наследования?
|
|||
---|---|---|---|
#18+
Павел Воробьевфункции выполняются в отдельных потоках и друг о друге они вообще ничего не знают. Неверно. Запускаемый процесс наследует ВСЕ хэндлы запускающего. Вне зависимости от того в каком потоке они были открыты. Posted via ActualForum NNTP Server 1.5 ... |
|||
:
Нравится:
Не нравится:
|
|||
21.10.2021, 16:04 |
|
Как закрыть handle переданный процессу в порядке наследования?
|
|||
---|---|---|---|
#18+
Dimitry Sibiryakov Павел Воробьевфункции выполняются в отдельных потоках и друг о друге они вообще ничего не знают. Неверно. Запускаемый процесс наследует ВСЕ хэндлы запускающего. Вне зависимости от того в каком потоке они были открыты. Спасибо, учту. Видимо по этому хендлы и прилипали к оставшимся процессам. Я почему-то думал что OmniThreadLibrary всё изолирует внутри потока. ... |
|||
:
Нравится:
Не нравится:
|
|||
21.10.2021, 16:07 |
|
Как закрыть handle переданный процессу в порядке наследования?
|
|||
---|---|---|---|
#18+
Павел Воробьевпоставил FreeAndNil(conout); сразу после CreateProcess и всё нормализовалось! Просто окно гонок потоков стало и тебе повезло на этот раз. Лучше таки запуск дочерних процессов жёстко сериализовать. Posted via ActualForum NNTP Server 1.5 ... |
|||
:
Нравится:
Не нравится:
|
|||
21.10.2021, 16:18 |
|
Как закрыть handle переданный процессу в порядке наследования?
|
|||
---|---|---|---|
#18+
Dimitry Sibiryakov Павел Воробьевпоставил FreeAndNil(conout); сразу после CreateProcess и всё нормализовалось! Просто окно гонок потоков стало и тебе повезло на этот раз. Лучше таки запуск дочерних процессов жёстко сериализовать. Еще раз перечитал ваши ответы, и только сейчас пришло осознание. Получается да, просто повезло и проблему это не решает. Получает когда я запускаю допустим 100 разных процессов пишущие в 100 разных файлов (консольный вывод) и делаю это параллельно через потоки, то им передаются ВСЕ открытые хендлы, и файлов, и потоков и всего всего всего. Это получается как снежный ком, более поздним процессам будет передаваться огромная куча отрытых хенлов для других процессов? Наконец я понял. Но смотрите, если я сериализую запуск, я понимаю что это решит проблему на корню, но это замедлит старт в 10 раз. Неужели нет никакого решения, чтобы передавать запускаемым процессам не все открытые хендлы, а только один, который указываю. GunSmoker подал идеи, но там я так понял всё для последовательного запуска. GunSmoker может есть идеи как сделать всё параллельно? Я в печали( использовать StartupInfoEx. GunSmoker, подскажите пожалуйста, у вас нет в загашнике примера кода для StartupInfoEx чтобы один хендл передать? ... |
|||
:
Нравится:
Не нравится:
|
|||
21.10.2021, 16:29 |
|
Как закрыть handle переданный процессу в порядке наследования?
|
|||
---|---|---|---|
#18+
Всё, ответ нашел тут: https://stackoverflow.com/questions/60563608/how-to-pass-a-pointer-to-a-list-of-handles-to-the-updateprocthreadattribute-func Всем большое спасибо, GunSmoker, благодарю за наводку :) ... |
|||
:
Нравится:
Не нравится:
|
|||
21.10.2021, 16:42 |
|
Как закрыть handle переданный процессу в порядке наследования?
|
|||
---|---|---|---|
#18+
Павел ВоробьевНо смотрите, если я сериализую запуск, я понимаю что это решит проблему на корню, но это замедлит старт в 10 раз. Нет, не замедлит если сделать всё правильно. Замедлить в 10 и более раз как раз способен одновременный запуск при котором бутылочным горлышком становится диск с позиционированием. Posted via ActualForum NNTP Server 1.5 ... |
|||
:
Нравится:
Не нравится:
|
|||
21.10.2021, 16:44 |
|
Как закрыть handle переданный процессу в порядке наследования?
|
|||
---|---|---|---|
#18+
Dimitry Sibiryakov Павел ВоробьевНо смотрите, если я сериализую запуск, я понимаю что это решит проблему на корню, но это замедлит старт в 10 раз. Нет, не замедлит если сделать всё правильно. Замедлить в 10 и более раз как раз способен одновременный запуск при котором бутылочным горлышком становится диск с позиционированием. Возможно, но зачем делать последовательно, если как оказалось есть возможность сделать параллельно через StartupInfoEx и передачу процессу только одного хэндла. ... |
|||
:
Нравится:
Не нравится:
|
|||
21.10.2021, 16:50 |
|
Как закрыть handle переданный процессу в порядке наследования?
|
|||
---|---|---|---|
#18+
Павел Воробьевно зачем делать последовательно, если как оказалось есть возможность сделать параллельно Повторяю медленно: затем, что параллельный запуск может быть в 10 и более раз медленнее. Posted via ActualForum NNTP Server 1.5 ... |
|||
:
Нравится:
Не нравится:
|
|||
21.10.2021, 17:08 |
|
Как закрыть handle переданный процессу в порядке наследования?
|
|||
---|---|---|---|
#18+
А зачем так извращаться, если можно дочерним процессом писать в STDOUT? ... |
|||
:
Нравится:
Не нравится:
|
|||
21.10.2021, 18:07 |
|
Как закрыть handle переданный процессу в порядке наследования?
|
|||
---|---|---|---|
#18+
Fr0sT-Brutal А зачем так извращаться, если можно дочерним процессом писать в STDOUT? Можно конечно, но запускаются совершенно разные процессы делающие совершенно разную работу, нельзя смешивать вывод, а вот записать его нужно обязательно. Некоторые инженерные программы сами в файл не умеют, только в консоль. ... |
|||
:
Нравится:
Не нравится:
|
|||
21.10.2021, 18:30 |
|
Как закрыть handle переданный процессу в порядке наследования?
|
|||
---|---|---|---|
#18+
Павел Воробьев Можно конечно, но запускаются совершенно разные процессы делающие совершенно разную работу, нельзя смешивать вывод, а вот записать его нужно обязательно. Некоторые инженерные программы сами в файл не умеют, только в консоль. И как это противоречит тому, что я предложил? Пусть себе пишут в консоль, а ты лови вывод и пиши уже куда душе угодно ... |
|||
:
Нравится:
Не нравится:
|
|||
22.10.2021, 10:24 |
|
|
start [/forum/topic.php?fid=58&msg=40105921&tid=2036939]: |
0ms |
get settings: |
11ms |
get forum list: |
14ms |
check forum access: |
4ms |
check topic access: |
4ms |
track hit: |
39ms |
get topic data: |
10ms |
get forum data: |
2ms |
get page messages: |
55ms |
get tp. blocked users: |
1ms |
others: | 273ms |
total: | 413ms |
0 / 0 |