2013-05-29 10 views
15

Potrzebuję odczytać dane dostarczone przez proces zewnętrzny za pośrednictwem pliku pospisowego pliku w moim programie Rust. Połączenie fd utrzymuje się przez bardzo długi czas (godziny), a druga strona przekazuje mi dane od czasu do czasu. Muszę więc nieprzerwanie czytać i przetwarzać strumień danych.Jak radzić sobie z blokowaniem wejścia/wyjścia w Rust lub długimi uruchomieniami wywołań funkcji zewnętrznych Ogólnie

Aby to zrobić, napisałem pętlę, która wywołuje libc::read() (readv faktycznie), aby odczytać dane i przetworzyć je po otrzymaniu. Ponieważ to zablokowałoby cały harmonogram, uruchamiam zadanie na nowym harmonogramie (task::spawn_sched(SingleThreaded)). Działa to dobrze, dopóki działa, ale po prostu nie mogę znaleźć sposobu na łatwe zamknięcie pętli.

Ponieważ pętla jest blokowana przez większość czasu, nie mogę użyć portu/kanału, aby powiadomić pętlę o zakończeniu.

Próbowałem zabić zadanie pętli, biorąc go w dół za pomocą nieudanego powiązanego zadania (odradzić zadanie pętli nadzorowane, odradzić połączone zadanie w nim i czekać na sygnał na porcie, aby zdarzyć się przed fail!() i usunięciem Zadanie pętli z nim). To działa dobrze w testach, ale libc::read() nie jest przerwana (zadanie nie powiedzie przed wykończeń odczytu i uderza task::yield() na jakiś czas.

Nauczyłem się wiele, patrząc na źródłach libcore, ale nie może wydawać znalezienie właściwego rozwiązania.

  1. Czy istnieje sposób, aby zabić (dziecko) zadanie w Rust nawet jeśli to robi jakąś długą zewnętrznego połączenia funkcjonował jak blokowanie czytać?
  2. Czy istnieje sposób, aby zrobić nonblocking czyta na posix filedeskryptor, aby Rust zachowywał kontrolę nad zadaniem?
  3. Jak mogę reagować na sygnały, np. sol. SIGTERM, jeśli użytkownik zakończy mój program. W Rust nie ma jeszcze czegoś takiego jak sigaction()?
+0

Wydaje się jakby to nie jest możliwe obecnie, ale nie trwają wysiłki w celu poprawy async I/O: https://github.com/mozilla/rust/issues/4419 – Zargony

+0

są jakieś aktualizacje na non-blokowanie I/O teraz w Rust 1.0? – jocull

+0

Ten komentarz jest dużo późniejszy, ale ponieważ pytanie nie ma zaakceptowanej odpowiedzi, umieszczam to tutaj: historia o io zmieniła się całkiem od 1.0. Obecnie skupiamy się na asynchronicznym i/o użyciu mio, opartym na bibliotekach jądra Linux i Windows (nie pamiętam ich z ręki). Wkrótce może pojawić się funkcja poziomu składni. Mówiąc ogólniej, jeśli wątek roboczy ma pętlę roboczą, pętla ta może sprawdzić komunikat zamknięcia. Jeśli jest zablokowany na i/o, nie wiem, czy można go obudzić. Byłbym zainteresowany, aby dowiedzieć się więcej na ten temat. – derekdreery

Odpowiedz

1
  1. Według mozila, zabijając zadanie ma więcej możliwości, na razie, nie mówiąc już o zablokowaniu odczytu.
  2. Będzie można to zrobić po mozilla/rust/pull/11410, zobacz także mój inny raport dotyczący problemu dla rust-zmq erickt/rust-zmq/issues/24, który również zależy od tego. (przepraszam za linki)
  3. Może signal listener będzie działać dla ciebie.
Powiązane problemy