1

以下代码生成一个“用户事件”,由以下代码返回poll

extern crate mio;

use mio::event::Evented;
use mio::{Events, Poll, PollOpt, Ready, Registration, Token};
use std::thread::{sleep, spawn, JoinHandle};
use std::time::{Duration, Instant};

#[derive(Debug)]
struct Output(u32, Duration);

pub struct MioThread {
    registration: Registration,
    handle: JoinHandle<Output>,
}

impl MioThread {
    pub fn new(i: u32) -> MioThread {
        let now = Instant::now();

        let (registration, set_readiness) = Registration::new2();

        let handle = spawn(move || {
            sleep(Duration::from_millis((1000 - (100 * i)) as u64));

            set_readiness.set_readiness(Ready::readable()).unwrap();

            Output(i, now.elapsed())
        });

        MioThread {
            registration: registration,
            handle: handle,
        }
    }

    // manage the thread result
    fn eval_result(self) {
        let out = self.handle.join();
        println!("do whathever you want with: {:?}", out.unwrap());
    }
}

fn main() {
    let poll = Poll::new().unwrap();

    let mut events = Events::with_capacity(16);

    let mut tasks = Vec::new();
    for i in 0..5 {
        let mio_thread = MioThread::new(i);

        mio_thread
            .registration
            .register(&poll, Token(i as usize), Ready::readable(), PollOpt::edge())
            .unwrap();

        tasks.push(Some(mio_thread));
    }

    loop {
        let num_events = poll.poll(&mut events, None).unwrap();
        println!("poll fired: {} events", num_events);
        for event in &events {
            if event.readiness().is_readable() {
                let Token(thread_id) = event.token();

                if let Some(t) = tasks.remove(thread_id) {
                    t.eval_result();
                }

            }
        }
    }
}

输出是:

poll fired: 1 events
do whathever you want with: Output(4, Duration { secs: 0, nanos: 600967623 })
poll fired: 0 events
poll fired: 1 events
do whathever you want with: Output(3, Duration { secs: 0, nanos: 701035026 })
poll fired: 0 events
poll fired: 1 events
do whathever you want with: Output(2, Duration { secs: 0, nanos: 801089370 })
poll fired: 0 events
poll fired: 1 events
do whathever you want with: Output(1, Duration { secs: 0, nanos: 900890190 })
poll fired: 0 events
poll fired: 1 events
do whathever you want with: Output(0, Duration { secs: 1, nanos: 600076 })
poll fired: 0 events

在 Mio 存储库上打开了一个问题

4

1 回答 1

0

如评论中所述并在此处确认:

删除注册可能会唤醒循环(确实如此,与注册相同)而不会实际触发事件

在大多数情况下,这显然不是问题,只是我在阅读文档后没想到的行为:

fn poll(&self, events: &mut Events, timeout: Option) -> Result[−] 等待就绪事件

阻塞当前线程并等待已向此 Poll 实例注册的任何 Evented 句柄的就绪事件。该函数将阻塞,直到至少收到一个就绪事件或超时已过。None 的超时意味着 poll 将阻塞,直到收到准备就绪事件。

当前线程在删除Registration.

于 2018-05-08T14:15:03.127 回答