[rust-dev] Mutiplexing I/O within a task

Fantix King fantix.king at gmail.com
Mon Jul 7 07:56:12 PDT 2014



> 在 2014年7月5日,下午11:07,Nat Pryce <nat.pryce at gmail.com> 写道:
> 
> I've been trying to write tasks that wait for both I/O and channel communication. I've been told that, to maximise communication performance, channels do not support selecting of both channels and I/O objects.  Therefore a program should signal to a task that is waiting for I/O over another I/O object, such as a pipe, not by sending a message over a channel.  Fair enough.

I was thinking about almost the same thing when trying zmq.rs, but end up with something very different, which might be a bit different than what is in the thread topic. The ioserver solution will certainly work, yet I'm trying to do it differently.

Let me try to start with your problem here - why it is wanted to wait on both I/O and channel communication? For my case, I had two reasons: (please let me know if your case is different)

1. Both I/O and channel may produce data at any time in any order for one piece of logic (task) to handle
2. It is wanted that the blocking I/O call can somehow be interrupted so that other code can run cooperatively.

For 1 I simply wrapped the I/O operation in a separate Task, communicating with the main Task with a normal channel, which can then be selected together with other channels. With libgreen I think it is a pretty direct decision, because Tasks are very cheap and cooperatively scheduled under the hood which is exactly what we wanted. With libnative it is a bit ugly, there might be hundreds of Tasks to create, so it might be sane to mix in a libgreen scheduler here for those Tasks.

As for 2, it does not need to be interrupted for task scheduling any more. However interrupt is still wanted in order to, for example, shutdown the Task. I used a timeout on the I/O operation (thanks to recent changes in Rust), so when the rest of the world is gone, the I/O call times out shortly and the Task fails trying to report the timeout through a broken channel. Drawback is the program freezes for a while on exit. For socket I/O it is also possible to be interrupted by close_read() or close_write() calls.

Please see also my blog post http://blog.segmentfault.com/fantix/1190000000593564 and tcp_lisrener.rs of zmq.rs https://github.com/zeromq/zmq.rs/blob/master/src/tcp_listener.rs.

I'd love to know if my solution for I/O is reasonable too.

BR,
Fantix

> 
> What API should I use to wait for multiple I/O objects within a task?  Is there a runtime-independent API for this?
> 
> And if I write my own I/O abstractions, for example around eventfd on Linux, what traits (platform specific traits, I imagine) should I implement to make them work with the runtime-independent I/O select API?
> 
> Sorry if this is already covered in the documentation.  I've searched but not found anything obvious.
> 
> Any help much appreciated.
> 
> --Nat
> 
> _______________________________________________
> Rust-dev mailing list
> Rust-dev at mozilla.org
> https://mail.mozilla.org/listinfo/rust-dev
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/rust-dev/attachments/20140707/a4bf6a60/attachment.html>


More information about the Rust-dev mailing list