|
10 / 11 / 2
Регистрация: 18.02.2012
Сообщений: 140
|
|||||||||||
Принудительный разрыв именованного канала26.01.2014, 15:35. Показов 3265. Ответов 13
Метки нет (Все метки)
Приветствую.
Есть группа многопоточных приложений которые обмениваются между собой информацией через именованные каналы. Приложения полностью не зависимы с способны восстанавливать соединения при падении одного из них. Суть проблемы в следующем - при попытки "штатно" закрыть приложение, мне нужно разорвать соединение, т.к. одна из ключевых проверок, является проверка работы потока который читает/пишет данные в канал. Суть в том, что функции:
0
|
|||||||||||
| 26.01.2014, 15:35 | |
|
Ответы с готовыми решениями:
13
Закрытие именованного канала при завершении работы программы
Странное поведение именованного канала |
|
Ушел с форума
|
|
| 26.01.2014, 15:59 | |
|
Делать DisconnectNamedPipe канала в одном потоке, в то время как другой
ждет завершения ReadFile на нем - не очень хорошая идея. Я бы переделал все на асинхронный лад. Тогда для отмены можно было бы использовать функцию CancelIo(Ex), да и читающий поток мог бы легко завершить работу, не дожидаясь, пока придут данные.
0
|
|
|
10 / 11 / 2
Регистрация: 18.02.2012
Сообщений: 140
|
||||||||
| 26.01.2014, 16:13 [ТС] | ||||||||
0
|
||||||||
|
Ушел с форума
|
|||
| 26.01.2014, 16:42 | |||
|
Можете привести минимальный пример, воспроизводящий проблему ?
Просто в работе с каналами масса нюансов: как оба потока открывают канал - через CreateNamedPipe/CreateFile или через передачу хэндлов, или через DuplicateHandle(Ex), какие флаги при создании указываются, особенности синхронного/асинхронного I/O и т.д.
0
|
|||
|
10 / 11 / 2
Регистрация: 18.02.2012
Сообщений: 140
|
||||||||||||||||||
| 26.01.2014, 16:50 [ТС] | ||||||||||||||||||
|
На сервере (C++)
На клиенте (С#)
Добавлено через 2 минуты
0
|
||||||||||||||||||
|
Ушел с форума
|
|
| 26.01.2014, 16:51 | |
|
Минимальный код, воспроизводящий проблему - тот, который можно
загнать копи-пастом в Visual Studio, скомпилировать и получить наблюдаемый результат. По-другому я вряд ли смогу помочь.
0
|
|
|
10 / 11 / 2
Регистрация: 18.02.2012
Сообщений: 140
|
||
| 26.01.2014, 17:28 [ТС] | ||
|
Эх, спасибо и на этом. Попробую сам поколдовать, может и найду в чем фокус. Добавлено через 31 минуту Методом научного тыка, для моего случая подошла функция CancelIoEx(this->pipeServer, NULL); Правда я не понял каким боком она заработала, если я на серверной стороне использую ReadFile(...). Возможно, клиент, реализуемый на C#, использует именно ReadFileEx(...), из-за этого CancelIo(this->pipeServer); и не срабатывал, хотя и ошибку тоже не выдавал.
0
|
||
|
Ушел с форума
|
|||||||
| 26.01.2014, 17:52 | |||||||
|
Все дело в том, что использовать один и тот же хэндл из разных потоков в
общем случае небезопасно. Например, что будет, если поток А все время будет звать ReadFile, а поток Б - WriteFile ? Система должна как-то синхронизировать эти обращения к общему объекту, в данном примере это файл. То есть, сначала будет выполнена ReadFile, потом WriteFile, или наоборот. Если один поток запустил длительную I/O-операцию и ждет ее завершения, а второй сразу же после этого вызвал, к примеру, DisconnectNamedPipe, то ему придется подождать своей очереди. Вот почему в Вашем примере она не отрабатывает как положено, то есть не разрывает соединение сразу. Вот, набросал такой примерчик: Кликните здесь для просмотра всего текста
Здесь происходит следующее: main создает именованный канал, а затем ожидает входящих подключений, запуская второй поток, имитирующий работу клиента. Клиент выдерживает небольшую паузу (2 секунды), затем подключается к каналу, потом снова выдерживает паузу (4 секунды), записывает сообщение в канал и завершает работу. main отображает сообщение и тоже завершается. Если раскомментировать макрос ABORT_PIPE, в игру входит третий поток. Он зовет DisconnectNamedPipe после того, как клиент подключается к каналу, но до того, как тот успеет отправить сообщение. Что интересно, на связи клиента и сервера это почти никак не отображается - клиент все равно отправляет сообщение, который main успешно принимает и отображает в консоли. Что косвенным образом подтверждает рассуждения выше о внутренних системных очередях и синхронизации. А вот DisconnectNamedPipe в main завершается, как и следовало ожидать, ошибкой, так как функция уже была вызвана в другом потоке, просто выполнена она была не сразу. Вот почему ее использование очень ограничено. А у CancelIoEx такого недостатка нет. Правда, доступна она только в Vista и выше...
0
|
|||||||
|
10 / 11 / 2
Регистрация: 18.02.2012
Сообщений: 140
|
||
| 26.01.2014, 18:04 [ТС] | ||
|
Или чего-то я не понимаю?
0
|
||
|
Ушел с форума
|
|
| 26.01.2014, 18:09 | |
|
0
|
|
|
10 / 11 / 2
Регистрация: 18.02.2012
Сообщений: 140
|
||
| 26.01.2014, 18:10 [ТС] | ||
|
Не по теме: Если честно, то я сам путаюсь и не могу себе представить ситуации, если одновременно читать и писать данные в канал на одной стороне, и читать/писать данные на другой. По любому что-то не срастется в итоге. Но при этом мне нужна была возможность закрыть приложение с команды введенной в консольную строку, а это, естественно, третий поток. Вот и стал мучатся с разрывом.
0
|
||
|
Ушел с форума
|
||
| 26.01.2014, 18:14 | ||
|
Если CancelIoEx недоступна, т.е. мы в XP/Server2003, тогда ничего другого не остается, кроме как отправить сообщение потоку, который инициировал операцию, чтобы он вызвал CancelIo. Операция, естественно, должна быть асинхронной.
1
|
||
|
10 / 11 / 2
Регистрация: 18.02.2012
Сообщений: 140
|
|||
| 26.01.2014, 18:15 [ТС] | |||
|
Добавлено через 1 минуту
0
|
|||
|
Ушел с форума
|
|
| 26.01.2014, 18:17 | |
|
Асинхронный I/O может быть очень разным.
Например, вы можете в одном потоке запустить десяток операций, а затем ждать, пока хотя бы одна из них завершится. Потом выполнить обработку, запустить новую порцию операций и снова ждать. И так далее. А можно запустить целый ворох потоков и каждому раздать пачку хэндлов, открытых в асинхронном режиме, пущай работают... А можно эти хэндлы связать с портом завершения ввода-вывода, а пул потоков заставить выгребать из него завершенные операции и заниматься их обработкой...
0
|
|
| 26.01.2014, 18:17 | |
|
Помогаю со студенческими работами здесь
14
WCF принудительный разрыв подлючения Принудительный разрыв интернет-соединения Передача массива с помощью именованного канала от сервера клиенту Как сделать принудительный перенос (разрыв) слова, если оно не умещается в блоке?
Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |
|
Новые блоги и статьи
|
|||
|
Реалии
Hrethgir 01.03.2026
Нет, я не закончил до сих пор симулятор. Эта задача сложнее. Не получилось уйти в плавсостав, но оно и к лучшему, возможно. Точнее получалось - но сварщиком в палубную команду, а это значит, в моём. . .
|
Ритм жизни
kumehtar 27.02.2026
Иногда приходится жить в ритме, где дел становится всё больше, а вовлечения в происходящее — всё меньше. Плотный график не даёт вниманию закрепиться ни на одном событии. Утро начинается с быстрых,. . .
|
SDL3 для Web (WebAssembly): Сборка библиотек: SDL3, Box2D, FreeType, SDL3_ttf, SDL3_mixer и SDL3_image из исходников с помощью CMake и Emscripten
8Observer8 27.02.2026
Недавно вышла версия 3. 4. 2 библиотеки SDL3. На странице официальной релиза доступны исходники, готовые DLL (для x86, x64, arm64), а также библиотеки для разработки под Android, MinGW и Visual Studio. . . .
|
SDL3 для Web (WebAssembly): Реализация движения на Box2D v3 - трение и коллизии с повёрнутыми стенами
8Observer8 20.02.2026
Содержание блога
Box2D позволяет легко создать главного героя, который не проходит сквозь стены и перемещается с заданным трением о препятствия, которые можно располагать под углом, как верхнее. . .
|
|
Конвертировать закладки radiotray-ng в m3u-плейлист
damix 19.02.2026
Это можно сделать скриптом для PowerShell. Использование
. \СonvertRadiotrayToM3U. ps1 <path_to_bookmarks. json>
Рядом с файлом bookmarks. json появится файл bookmarks. m3u с результатом.
# Check if. . .
|
Семь CDC на одном интерфейсе: 5 U[S]ARTов, 1 CAN и 1 SSI
Eddy_Em 18.02.2026
Постепенно допиливаю свою "многоинтерфейсную плату". Выглядит вот так:
https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11617&stc=1&d=1771445347
Основана на STM32F303RBT6.
На борту пять. . .
|
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
|
И ясному Солнцу
zbw 12.02.2026
И ясному Солнцу,
и светлой Луне.
В мире
покоя нет
и люди
не могут жить в тишине.
А жить им немного лет.
|