Кросс-платформенный (linux / Win32) неблокирующий ввод-вывод C ++ на stdin / stdout / stderr

Я пытаюсь найти лучшее решение для неблокирующего ввода-вывода через stdin / stdout со следующими характеристиками:

  • Пока данных достаточно, считывайте их фрагментами размером n.
  • Если данных недостаточно, считайте частичный фрагмент.
  • Если данных нет, блокируйте их, пока они не появятся (даже если они меньше n).

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

Я знаю, что могу добиться этого, используя потоки и цикл istream :: get () или написав кучу кода, зависящего от платформы (поскольку вы не можете выбрать () для дескрипторов файлов в Windows) ... ((Там также istream :: readsome (), что кажется многообещающим, но единственные результаты, которые я могу найти в Google, были люди, которые говорят, что это на самом деле не работает хорошо.))

Поскольку я не особо много писал с этими API, возможно, есть способ получше.


person Dan S.    schedule 24.11.2008    source источник


Ответы (3)


Возможно, вам пригодится boost :: asio ?

person activout.se    schedule 24.11.2008
comment
Это выглядит многообещающе (большой молоток для небольшой проблемы, но, вероятно, стоит изучить) ... Спасибо! - person Dan S.; 24.11.2008
comment
Да, это, вероятно, ваш лучший выбор для переносимого асинхронного ввода-вывода, поскольку в языке нет встроенной поддержки неблокирующих потоков ввода-вывода или. Вам придется использовать какую-то библиотеку, и ускорение обычно является хорошей ставкой. - person jalf; 24.11.2008
comment
(Если бы только Win32 поддерживал select () или poll () для произвольных дескрипторов, а не только для сокетов) ... Покопавшись, я подтвердил, что могу делать то, что мне нужно, и есть даже руководство по его настройке: highscore.de/boost/process/process / - person Dan S.; 24.11.2008
comment
Приложение: Учебное пособие предназначено для перехвата stdin / stdout дочернего процесса с использованием асинхронных потоков; я хочу, чтобы мой собственный процесс обрабатывал свой собственный stdin / stout асинхронно. Тем не менее, это хорошие 90% пути. - person Dan S.; 24.11.2008
comment
@DanS .: Вы когда-нибудь находили 100% решение? Сейчас я пытаюсь решить ту же проблему - person John Dibling; 07.06.2012

Я использовал потоки и код платформы. См. мой ответ на другой вопрос. Мне удалось поместить специфичные для ОС вещи в inputAvailable () (Linux использует select, Windows просто возвращает true). Затем я мог бы использовать WaitForSingleObject () с тайм-аутом в Windows, чтобы попытаться завершить поток, а затем TerminateThread (), чтобы убить его. Очень некрасиво, но команда не хотела использовать это усиление.

person jwhitlock    schedule 14.08.2009
comment
Это только ссылки на некросс-платформенное решение (также включает несколько устаревших ссылок). Есть ли у вас где-нибудь оригинальная реализация? - person helmesjo; 28.02.2020
comment
Извините, это была предыдущая компания, у меня больше нет этого кода. Я считаю, что код inputAvailable() - это решение для Linux. Посмотрите _kbit() в качестве отправной точки для Windows: docs.microsoft.com/en-us/cpp/c-runtime-library/reference/ - person jwhitlock; 28.02.2020

Я сделал что-то похожее на jwhitlock ... В итоге я получил класс StdinDataIO, который обертывает соответствующую реализацию для конкретной ОС (*), чтобы остальная часть моей программы могла выбрать () в дескрипторе файла, который предоставляет StdinDataIO, оставаясь блаженно игнорирующим Ограничения Windows относительно stdin. Посмотрите здесь и здесь, если хотите, весь код имеет открытый исходный код / ​​лицензию BSD.

(*) реализация является простой сквозной передачей для Linux / MacOSX, а в Windows это довольно сложный процесс настройки дочернего потока для чтения из стандартного ввода и отправки данных, которые он получает через сокет, обратно в основной поток .. не очень изящно, но работает.

person Jeremy Friesner    schedule 14.08.2009