首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么Mio的投票因用户生成的事件被触发了两次?

为什么Mio的投票因用户生成的事件被触发了两次?
EN

Stack Overflow用户
提问于 2018-05-03 06:02:06
回答 1查看 239关注 0票数 1

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

代码语言:javascript
复制
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();
                }

            }
        }
    }
}

产出如下:

代码语言:javascript
复制
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存储库的一个问题

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-05-08 14:15:03

如评论和确认的这里中所述

删除注册可能会唤醒循环(它确实是这样做的,就像注册一样),而不会真正触发事件

在大多数情况下,这显然不是一个问题,只是在阅读了文档之后我没有预料到的行为。

fn轮询(&self,events:&mut,timeout: Option) ->结果−等待就绪事件 阻塞当前线程,并等待已在此Poll实例中注册的任何事件句柄的就绪事件。该函数将被阻塞,直到至少接收到一个就绪事件或超时。超时不意味着在收到就绪事件之前投票将被阻止。

在删除Registration时,也确实会唤醒当前线程。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50147956

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档