2008-11-24 8 views
8

staram się znaleźć najlepsze rozwiązanie dla powodują blokowania IO poprzez stdin/stdout z następujących cech:wielu platform (linux/Win32) nonblocking C++ IO na stdin/stdout/stderr

  • Dopóki jest wystarczająca ilość danych, przeczytanych w rozmiarach o rozmiarach n.
  • Jeśli nie ma wystarczającej ilości danych, przeczytaj częściowy fragment.
  • Jeśli nie ma dostępnych danych, zablokuj, aż pojawią się jakieś (choć może być mniejsze niż n).

Celem jest umożliwienie wydajnego transferu dużych zbiorów danych przy jednoczesnym natychmiastowym przetwarzaniu kodów "kontrolnych" (zamiast utrzymywania ich w jakimś częściowo wypełnionym buforze).

Wiem, że mogę to osiągnąć za pomocą wątków i pętli istream :: get() lub poprzez napisanie pakietu specyficznego dla platformy kodu (ponieważ nie można wybrać() na uchwytach plików w oknach). (Istnieje również istream :: readsome(), który wydaje się obiecujący, ale jedyne wyniki, jakie mogę znaleźć w Google, to ludzie, którzy twierdzą, że tak naprawdę nie działa dobrze.))

Ponieważ niewiele zrobiłem kodowanie w/tych API, być może jest lepszy sposób.

Odpowiedz

6

Może może być dla ciebie przydatny ?

+0

To wygląda raczej obiecująco (duży młotek za mały problem, ale prawdopodobnie warto się uczyć) ... Dzięki! –

+0

Tak, to prawdopodobnie najlepszy sposób na przenośne asynchroniczne operacje we/wy, ponieważ język nie ma natywnej obsługi dla niezablokowanych wątków I/O * lub *. Będziesz musiał użyć jakiejś biblioteki, a zwiększenie to zazwyczaj dobry zakład. – jalf

+0

(Jeśli tylko Win32 obsługuje select() lub poll() na arbitralnych uchwytach zamiast tylko gniazdach) ... Po wykonaniu kopania potwierdziłem, że mogę zrobić to, czego potrzebuję i istnieje nawet samouczek do ustawienia w górę: http://www.highscore.de/boost/process/process/tutorials.html#process.tutorials.async_io –

1

Użyłem wątków i specyficznego dla platformy kodu. Zobacz my answer to another question. Byłem w stanie umieścić specyficzne dla OS rzeczy w inputAvailable() (Linux używa select, Windows po prostu zwraca true). Mógłbym wtedy użyć WaitForSingleObject() z limitem czasu w systemie Windows, aby spróbować zakończyć wątek, a następnie TerminateThread(), aby go zabić. Bardzo brzydki, ale zespół nie chciał użyć tego odrobiny wzmocnienia.

0

Zrobiłem coś podobnego do jwhitlocka ... Skończyłem z klasą StdinDataIO, która owija się wokół odpowiedniej implementacji specyficznej dla systemu operacyjnego (*), aby reszta mojego programu mogła wybrać() na deskryptorze pliku StdinDataIO, pozostając błogo nieświadomymi ograniczeń Windows dotyczących stdin. Wystarczy spojrzeć na kod: here i here, kod jest objęty licencją open-source/BSD.

(*) implementacja jest prostym przejściem dla systemu Linux/MacOSX, a w systemie Windows jest dość złożonym procesem konfigurowania wątku podrzędnego do odczytu ze standardowego wejścia i wysyłania danych, które otrzymuje przez gniazdo do główny wątek ... niezbyt elegancki, ale działa.