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.
- 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ć?
- Czy istnieje sposób, aby zrobić nonblocking czyta na posix filedeskryptor, aby Rust zachowywał kontrolę nad zadaniem?
- 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()
?
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
są jakieś aktualizacje na non-blokowanie I/O teraz w Rust 1.0? – jocull
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