2008-11-24 14 views
8

Estoy tratando de encontrar la mejor solución para no bloqueante IO a través de la entrada estándar/salida estándar con las siguientes características:multiplataforma (Linux/Win32) sin bloqueo C++ IO en stdin/stdout/stderr

  • Mientras hay suficientes datos, lea en n -los trozos de tamaño.
  • Si no hay suficientes datos, lea en un fragmento parcial.
  • Si no hay datos disponibles, bloquee hasta que haya alguno (aunque puede ser más pequeño que n).

El objetivo es permitir una transferencia eficiente para grandes conjuntos de datos mientras se procesan códigos de "control" inmediatamente (en lugar de tenerlos en algún buffer parcialmente rellenado).

Sé que puedo lograr esto mediante el uso de subprocesos y un ciclo istream :: get(), o escribiendo un montón de código específico de plataforma (ya que no puede seleccionar() en los identificadores de archivo en Windows) .. . ((También hay istream :: readsome() que parece prometedor, pero los únicos resultados que puedo encontrar en google fueron de personas que dicen que en realidad no funciona bien.))

Como no he hecho mucho codificación con estas API, tal vez hay una mejor manera.

Respuesta

6

Tal vez boost::asio puede ser útil para usted?

+0

Eso parece bastante prometedor (un gran martillo para un pequeño problema, pero probablemente valga la pena aprenderlo) ... ¡Gracias! –

+0

Sí, esa es probablemente la mejor opción para E/S asíncronas portátiles, ya que el idioma no tiene soporte nativo para E/S * o * sin bloqueos. Tendrás que usar una biblioteca de algún tipo, y el impulso suele ser una buena apuesta. – jalf

+0

(Si solo Win32 admite select() o poll() en identificadores arbitrarios en lugar de sockets) ... Después de investigar, he confirmado que puedo hacer lo que necesito e incluso hay un tutorial para configurarlo arriba: http://www.highscore.de/boost/process/process/tutorials.html#process.tutorials.async_io –

1

Utilicé los hilos y el código específico de la plataforma. Ver my answer to another question. Pude poner las cosas específicas del sistema operativo en inputAvailable() (Linux usa Select, Windows simplemente devuelve true). Podría entonces usar WaitForSingleObject() con un tiempo de espera en Windows para tratar de dejar que el hilo se complete y luego terminarteThread() para matarlo. Muy feo, pero el equipo no quería usar este pequeño impulso.

0

Hice algo similar a jwhitlock ... Terminé con una clase StdinDataIO que envuelve la implementación apropiada del sistema operativo (*) para que el resto de mi programa pueda seleccionar() en el descriptor de archivo que proporciona StdinDataIO, permaneciendo felizmente ignorante de las limitaciones de Windows con respecto a stdin. Eche un vistazo a here y here si lo desea, el código es todo de código abierto/licencia BSD.

(*) la implementación es un simple paso para Linux/MacOSX, y en Windows es un proceso complejo de configurar un hilo hijo para leer desde stdin y enviar los datos que recibe a través de un socket a la hilo principal ... no muy elegante, pero funciona.