Примечание редактора: Этот вопрос относится к версии Rust до 1.0 и использует термины и функции, которых нет в коде Rust 1.0. Выраженные концепции по-прежнему актуальны.
Мне нужно прочитать данные, предоставленные внешним процессом через дескриптор файла POSIX в моей программе Rust. Соединение с файловым дескриптором поддерживается очень долго (часы), и другая сторона время от времени передает мне данные. Мне нужно читать и обрабатывать поток данных непрерывно.
Для этого я написал цикл, который вызывает libc::read()
(фактически readv
) для чтения данных и их обработки при получении. Так как это блокирует весь планировщик, я порождаю задачу в новом планировщике (task::spawn_sched(SingleThreaded)
). Это работает нормально, пока он работает, но я не могу найти способ аккуратно отключить цикл.
Поскольку цикл блокирует большую часть времени, я не могу использовать порт/канал, чтобы уведомить цикл о выходе.
Я попытался убить задачу цикла, сняв ее с помощью сбойной связанной задачи (создать задачу цикла под наблюдением, создать связанную задачу внутри нее и дождаться сигнала на порте, прежде чем произойдет fail!()
Вызывая и отключая цикл Задача с ним). Он хорошо работает в тестах, но libc::read()
не прерывается (задача не завершается неудачей, пока чтение не завершается, и через некоторое время она достигает task::yield()
.
Я многому научился, глядя на исходники libcore, но, похоже, не могу найти правильного решения.
- Есть ли способ убить (дочернюю) задачу в Rust, даже если она выполняет какой-то длинный внешний вызов функции, такой как блокирующее чтение?
- Есть ли способ сделать неблокирующее чтение для файлового дескриптора POSIX, чтобы Rust сохранял контроль над задачей?
- Как я могу реагировать на сигналы, например,
SIGTERM
если пользователь завершает мою программу? Кажется, в Rust пока что нет ничего похожего наsigaction()
.