IIRC everything in tokio::sync is runtime agnostic.
Edit: While not stated explicitly in the docs, I found a reference:
That said, some utilities do not need external code: For example a channel can coordinate the two halves and make one half wake the other half up, meaning that no external code is needed to handle that situation. In fact the entire tokio::sync module is executor agnostic for this reason. Additionally the entire futures crate provides exclusively executor agnostic utilities.
Technically yes, it can be done with just the futures crate:
use futures::channel::mpsc;
use futures::executor::block_on;
use futures::sink::SinkExt;
use futures::stream::StreamExt;
fn main() {
let (mut tx, mut rx) = mpsc::channel(100);
block_on(tx.send(42));
println!("received {} from channel", block_on(rx.next()).unwrap())
}
Note the use of block_on. It starts up a light weight single threaded executor that can run any future to completion, blocking the current thread until it's done.
I still think the first answer is better though. The tokio channel is actually designed to bridge the gap between sync and async worlds. Saves you the trouble of wrapping everything in block_on.
The mpsc channel does not care about which runtime you use it in, and can be used to send messages from one runtime to another. It can also be used in non-Tokio runtimes.
I see, I only checked the top-level documentation of the sync module. Might be worth expanding the docs in this regard maybe? Don't know how often questions like this topic or #4232 come up in practise and how to best share what parts of tokio are runtime-dependent and which aren't.
does that mean I can run an async function that uses rx, and block_on(tx) and it will not mess with the async function runtime, as the block_on runs in a different thread?
Well, block_on blocks the current thread. If your serial code is already running in it's own thread, then it's safe to call block_on. It sounds like it is, but I can't know for sure unless I see your code.
Neat, I hadn't seen flume before. The only other multi-producer, multi-consumer async channel I'd seen before was async_channel. I'll have to give it a more detailed look.