#async-io #coroutine #io #non-blocking #green #async #fiber

nightly zonyitoo/coio

带有非阻塞I/O支持的协程调度器

7 个版本

使用旧Rust 2015

0.2.0 2016年3月18日
0.1.5 2015年12月26日
0.1.3 2015年9月29日
0.1.2 2015年8月25日

#9 in #green

455 星 & 15 关注者

MIT/Apache

230KB
5.5K SLoC

协程I/O

Build Status Build status License

使用工作窃取算法的协程调度

警告:由于TLS内联,可能崩溃,请查看https://github.com/zonyitoo/coio-rs/issues/56获取更多详细信息!

功能

  • 非阻塞I/O
  • 工作窃取协程调度
  • 异步计算API

使用方法

注意:您必须使用Nightly Rust来构建此项目。

[dependencies.coio]
git = "https://github.com/zonyitoo/coio-rs.git"

基本协程

extern crate coio;

use coio::Scheduler;

fn main() {
    Scheduler::new()
        .run(|| {
            for _ in 0..10 {
                println!("Heil Hydra");
                Scheduler::sched(); // Yields the current coroutine
            }
        })
        .unwrap();
}

TCP回声服务器

extern crate coio;

use std::io::{Read, Write};

use coio::net::TcpListener;
use coio::{spawn, Scheduler};

fn main() {
    // Spawn a coroutine for accepting new connections
    Scheduler::new().with_workers(4).run(move|| {
        let acceptor = TcpListener::bind("127.0.0.1:8080").unwrap();
        println!("Waiting for connection ...");

        for stream in acceptor.incoming() {
            let (mut stream, addr) = stream.unwrap();

            println!("Got connection from {:?}", addr);

            // Spawn a new coroutine to handle the connection
            spawn(move|| {
                let mut buf = [0; 1024];

                loop {
                    match stream.read(&mut buf) {
                        Ok(0) => {
                            println!("EOF");
                            break;
                        },
                        Ok(len) => {
                            println!("Read {} bytes, echo back", len);
                            stream.write_all(&buf[0..len]).unwrap();
                        },
                        Err(err) => {
                            println!("Error occurs: {:?}", err);
                            break;
                        }
                    }
                }

                println!("Client closed");
            });
        }
    }).unwrap();
}

退出主函数

将导致所有挂起的协程被杀死。

extern crate coio;

use std::sync::Arc;
use std::sync::atomic::{AtomicUsize, Ordering};
use std::time::Duration;

use coio::Scheduler;

fn main() {
    let counter = Arc::new(AtomicUsize::new(0));
    let cloned_counter = counter.clone();

    let result = Scheduler::new().run(move|| {
        // Spawn a new coroutine
        Scheduler::spawn(move|| {
            struct Guard(Arc<AtomicUsize>);

            impl Drop for Guard {
                fn drop(&mut self) {
                    self.0.store(1, Ordering::SeqCst);
                }
            }

            // If the _guard is dropped, it will store 1 to the counter
            let _guard = Guard(cloned_counter);

            coio::sleep(Duration::from_secs(10));
            println!("Not going to run this line");
        });

        // Exit right now, which will cause the coroutine to be destroyed.
        panic!("Exit right now!!");
    });

    // The coroutine's stack is unwound properly
    assert!(result.is_err() && counter.load(Ordering::SeqCst) == 1);
}

基本基准测试

有关更多详细信息,请参阅基准测试

依赖项

~2.5MB
~41K SLoC