Структура Signal
pub struct Signal { /* private fields */ }
signal.Обработчик для получения сигналов ОС определённого типа.
Обработчик можно преобразовать в Stream с помощью SignalStream.
В целом обработка сигналов в Unix — довольно сложная тема, и эта структура не исключение! При использовании потоков Signal следует помнить о некоторых важных ограничениях:
-
Обработка сигналов в Unix уже требует в некоторых случаях объединения сигналов. Поток
Signalздесь тоже не исключение: он также объединяет сигналы. То есть даже если обработчик сигнала для этого процесса запустится несколько раз, потокSignalможет вернуть только одно уведомление о сигнале. В частности, до вызоваpollвсе уведомления о сигналах объединяются в один элемент, возвращаемый изpoll. Однако после вызоваpollследующий сигнал гарантированно будет выдан как элемент.Иными словами, каждый элемент, полученный из возвращённого обработчика, соответствует как минимум одному сигналу, но, возможно, и нескольким.
-
Обработка сигналов в целом относительно неэффективна. Хотя в этом crate возможны некоторые улучшения, не рекомендуется рассчитывать на одновременное открытие миллионов каналов сигналов.
Если у вас есть вопросы по этому поводу, можете создать issue в репозитории! Мы всегда рады новым подходам, позволяющим устранить некоторые из этих ограничений!
Предостережения
При первой регистрации экземпляра Signal для определённого типа сигнала устанавливается обработчик сигнала ОС, который заменяет стандартное поведение платформы при получении этого сигнала на всё время работы процесса.
Например, по умолчанию системы Unix завершают процесс при получении SIGINT. Но когда создаётся экземпляр Signal для прослушивания этого сигнала, следующий полученный SIGINT будет преобразован в событие потока, и выполнение процесса продолжится. Даже если этот экземпляр Signal будет удалён, последующие доставки SIGINT будут перехвачены Tokio, а стандартное поведение платформы НЕ будет восстановлено.
Поэтому приложениям следует позаботиться о том, чтобы после прослушивания определённых сигналов ожидаемое поведение сигналов сохранялось.
Примеры
Ожидание SIGHUP
use tokio::signal::unix::{signal, SignalKind};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// An infinite stream of hangup signals.
let mut sig = signal(SignalKind::hangup())?;
// Print whenever a HUP signal is received
loop {
sig.recv().await;
println!("got signal HUP");
}
}Реализации
impl Signal
pub async fn recv(&mut self) -> Option<()>
Получает следующее событие уведомления о сигнале.
Хотя этот метод возвращает Option<()>, фактически он никогда не вернёт None. Это было добавлено по ошибке, и удаление стало бы нарушающим совместимость изменением.
Безопасность при отмене
Этот метод безопасен при отмене. Если использовать его в качестве ветви в tokio::select! и первой завершится другая ветвь, гарантируется, что ни один сигнал не будет потерян.
Примеры
Ожидание SIGHUP
use tokio::signal::unix::{signal, SignalKind};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// An infinite stream of hangup signals.
let mut stream = signal(SignalKind::hangup())?;
// Print whenever a HUP signal is received
loop {
stream.recv().await;
println!("got signal HUP");
}
}pub fn poll_recv(&mut self, cx: &mut Context<'_>) -> Poll<Option<()>>
Проверяет получение следующего события уведомления о сигнале вне контекста async.
Хотя этот метод возвращает Option<()>, фактически он никогда не вернёт None. Это было добавлено по ошибке, и удаление стало бы нарушающим совместимость изменением.
Примеры
Опрос из вручную реализованного future
use std::pin::Pin;
use std::future::Future;
use std::task::{Context, Poll};
use tokio::signal::unix::Signal;
struct MyFuture {
signal: Signal,
}
impl Future for MyFuture {
type Output = Option<()>;
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
println!("polling MyFuture");
self.signal.poll_recv(cx)
}
}Реализации трейтов
Автоматические реализации трейтов
impl !RefUnwindSafe for Signal
impl !UnwindSafe for Signal
impl Freeze for Signal
impl Send for Signal
impl Sync for Signal
impl Unpin for Signal
impl UnsafeUnpin for Signal
Обобщённые реализации
impl<T> BorrowMut<T> for Twhere T: ?Sized,
fn borrow_mut(&mut self) -> &mut T
impl<T> Instrument for T
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn in_current_span(self) -> Instrumented<Self> ⓘ
impl<T> WithSubscriber for T
fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self> ⓘ
fn with_current_subscriber(self) -> WithDispatch<Self> ⓘ
Subscriber к этому типу и возвращает обёртку WithDispatch. Подробнее
MIT License
Copyright © Tokio Contributors
https://docs.rs/tokio/1.53.1/tokio/signal/unix/struct.Signal.html