У меня есть ручка трубы, которая была создана как перекрытая. Мне нужно читать и записывать данные в него параллельно. Как мне этого добиться?
Сервер именованных каналов с использованием перекрывающегося ввода-вывода На странице документации показан пример того, как читать и писать во многие каналы, но «это позволяет избежать одновременных операций на одном экземпляре канала».
Как правильно сделать это в C ++ на Windows? Я не могу подать правильный пример или какую-либо помощь по теме.
Основная проблема, с которой я сталкиваюсь, заключается в том, что обычные блоки ReadFile блокируются, когда нет данных для чтения, и в конце концов я не могу писать с помощью WriteFile. Я не нашел ни одного метода, который мог бы сказать мне, что есть что-то, что можно не блокировать. Насколько я понимаю, мне нужно передать структуру OVERLAPPED, но я не знаю, как использовать ее в случае параллельного чтения и записи в один канал (не много).
Это должно быть возможно, как сказано в Синхронный и перекрывающийся канал ввода / вывода:
Перекрывающиеся операции позволяют одному каналу одновременно считывать и записывать данные, а одному потоку — одновременно выполнять операции ввода-вывода для нескольких дескрипторов канала.
Все, что вам нужно сделать, это предоставить различную структуру OVERLAPPED для каждой из одновременных операций. В вашем случае все это означает, что каждый из двух потоков нуждается в своей собственной структуре OVERLAPPED. Поскольку потоки предположительно выполняют разные функции, это должно происходить автоматически, если вы не испортили это с помощью глобальной переменной.
Обратите внимание, что вы слишком усложняете ситуацию, начиная с этого примера, который сфокусирован на использовании перекрывающихся операций ввода-вывода, чтобы избежать необходимости в нескольких потоках.
Вместо этого представьте, что вы пишете каждую из двух функций с использованием неперекрывающегося ввода-вывода, но всякий раз, когда вы вызываете ReadFile или WriteFile, включайте допустимую структуру OVERLAPPED с дескриптором события и следите за WaitForSingleObject. Есть несколько вещей, которые вы должны знать: вы должны убедиться, что каждый из потоков создает свой собственный объект события, и вы должны обработать случай, когда операция ввода-вывода завершается немедленно (т.е. возвращает ERROR_SUCCESS вместо ERROR_IO_PENDING). В противном случае это все довольно просто.
Если вы не можете заставить его работать, покажите свой код.
Как документация для труб говорит, один процесс пишет, другой процесс читает. Если вы хотите ПРОЧИТАТЬ и ЗАПИСАТЬ, вам понадобятся два канала, один для «записи в другой процесс», а другой для «чтения данных из другого процесса».
[Это не уникально для Windows, но так как вы спрашиваете о каналах Windows, я подумал, что лучше всего дать документы по Windows. Linux / Unix трубы одинаково — у них есть два конца, конец чтения и конец записи]Конечно, как говорится в комментарии, похоже, что документация по Windows довольно противоречива (и я когда-либо использовал только каналы Windows в одном направлении за раз).
в то время как этот пример не читает и не пишет ОДНОВРЕМЕННО, я думаю, что его можно относительно легко изменить.
Я подозреваю (но так как код не опубликован), проблема заключается либо в вызове ReadFile, либо в настройке самого канала. Перекрытые вызовы ReadFile являются асинхронными, и вам нужно будет дождаться события, связанного с перекрытой структурой с WaitForMultipleObjects, прежде чем проверять результаты.
Очевидно, что если вы читаете и пишете одновременно, вам нужна одна перекрывающаяся структура для чтения и одна для записи, чтобы указать, какая сторона «завершила».