Использование перекрывающегося именованного канала для одновременного чтения и записи в Windows

У меня есть ручка трубы, которая была создана как перекрытая. Мне нужно читать и записывать данные в него параллельно. Как мне этого добиться?

Сервер именованных каналов с использованием перекрывающегося ввода-вывода На странице документации показан пример того, как читать и писать во многие каналы, но «это позволяет избежать одновременных операций на одном экземпляре канала».

Как правильно сделать это в C ++ на Windows? Я не могу подать правильный пример или какую-либо помощь по теме.

Основная проблема, с которой я сталкиваюсь, заключается в том, что обычные блоки ReadFile блокируются, когда нет данных для чтения, и в конце концов я не могу писать с помощью WriteFile. Я не нашел ни одного метода, который мог бы сказать мне, что есть что-то, что можно не блокировать. Насколько я понимаю, мне нужно передать структуру OVERLAPPED, но я не знаю, как использовать ее в случае параллельного чтения и записи в один канал (не много).

Это должно быть возможно, как сказано в Синхронный и перекрывающийся канал ввода / вывода:

Перекрывающиеся операции позволяют одному каналу одновременно считывать и записывать данные, а одному потоку — одновременно выполнять операции ввода-вывода для нескольких дескрипторов канала.

4

Решение

Все, что вам нужно сделать, это предоставить различную структуру OVERLAPPED для каждой из одновременных операций. В вашем случае все это означает, что каждый из двух потоков нуждается в своей собственной структуре OVERLAPPED. Поскольку потоки предположительно выполняют разные функции, это должно происходить автоматически, если вы не испортили это с помощью глобальной переменной.

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

Вместо этого представьте, что вы пишете каждую из двух функций с использованием неперекрывающегося ввода-вывода, но всякий раз, когда вы вызываете ReadFile или WriteFile, включайте допустимую структуру OVERLAPPED с дескриптором события и следите за WaitForSingleObject. Есть несколько вещей, которые вы должны знать: вы должны убедиться, что каждый из потоков создает свой собственный объект события, и вы должны обработать случай, когда операция ввода-вывода завершается немедленно (т.е. возвращает ERROR_SUCCESS вместо ERROR_IO_PENDING). В противном случае это все довольно просто.

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

3

Другие решения

Как документация для труб говорит, один процесс пишет, другой процесс читает. Если вы хотите ПРОЧИТАТЬ и ЗАПИСАТЬ, вам понадобятся два канала, один для «записи в другой процесс», а другой для «чтения данных из другого процесса».

[Это не уникально для Windows, но так как вы спрашиваете о каналах Windows, я подумал, что лучше всего дать документы по Windows. Linux / Unix трубы одинаково — у них есть два конца, конец чтения и конец записи]

Конечно, как говорится в комментарии, похоже, что документация по Windows довольно противоречива (и я когда-либо использовал только каналы Windows в одном направлении за раз).

в то время как этот пример не читает и не пишет ОДНОВРЕМЕННО, я думаю, что его можно относительно легко изменить.

Я подозреваю (но так как код не опубликован), проблема заключается либо в вызове ReadFile, либо в настройке самого канала. Перекрытые вызовы ReadFile являются асинхронными, и вам нужно будет дождаться события, связанного с перекрытой структурой с WaitForMultipleObjects, прежде чем проверять результаты.

Очевидно, что если вы читаете и пишете одновременно, вам нужна одна перекрывающаяся структура для чтения и одна для записи, чтобы указать, какая сторона «завершила».

1

По вопросам рекламы [email protected]