| Crates.io | kanal |
| lib.rs | kanal |
| version | 0.1.1 |
| created_at | 2022-07-13 12:30:18.229412+00 |
| updated_at | 2025-03-23 13:45:05.271449+00 |
| description | The fast sync and async channel that Rust deserves |
| homepage | |
| repository | https://github.com/fereidani/kanal |
| max_upload_size | |
| id | 625035 |
| size | 156,920 |
The fast sync and async channel that Rust deserves!
The Kanal library is a Rust implementation of channels inspired by the CSP (Communicating Sequential Processes) model. It aims to help programmers create efficient concurrent programs by providing multi-producer and multi-consumer channels with advanced features for fast communication. The library focuses on unifying message passing between synchronous and asynchronous parts of Rust code, offering a combination of synchronous and asynchronous APIs while maintaining high performance.
std-mutex feature and Kanal will perform better than competitors with that feature too.To use Kanal in your Rust project, add the following line to your Cargo.toml file:
[dependencies]
kanal = "0.1"
Sync channel example:
// Initialize a bounded sync channel with a capacity for 8 messages
let (sender, receiver) = kanal::bounded(8);
let s = sender.clone();
std::thread::spawn(move || {
s.send("hello")?;
anyhow::Ok(())
});
// Receive an example message in another thread
let msg = receiver.recv()?;
println!("I got msg: {}", msg);
// Convert and use channel in async context to communicate between sync and async
tokio::spawn(async move {
// Borrow the channel as an async channel and use it in an async context ( or convert it to async using to_async() )
sender.as_async().send("hello").await?;
anyhow::Ok(())
});
Async channel example:
// Initialize a bounded channel with a capacity for 8 messages
let (sender, receiver) = kanal::bounded_async(8);
sender.send("hello").await?;
sender.send("hello").await?;
// Clone receiver and convert it to a sync receiver
let receiver_sync = receiver.clone().to_sync();
tokio::spawn(async move {
let msg = receiver.recv().await?;
println!("I got msg: {}", msg);
anyhow::Ok(())
});
// Spawn a thread and use receiver in sync context
std::thread::spawn(move || {
let msg = receiver_sync.recv()?;
println!("I got msg in sync context: {}", msg);
anyhow::Ok(())
});
as_sync and as_async.Close function, enabling you to broadcast a close signal from any channel instance and close the channel for both senders and receivers.Results are based on how many messages can be passed in each scenario per second.
usize tests are transferring messages of size hardware pointer.big tests are transferring messages of 8x the size of the hardware pointer.N/A means that the test subject is unable to perform the test due to its limitations, Some of the test subjects don't have implementation for size 0 channels, MPMC or unbounded channels.
Machine: AMD Ryzen 9 9950X 16-Core Processor
Rust: rustc 1.85.1 (4eb161250 2025-03-15)
Go: go version go1.24.1 linux/amd64
OS (uname -a): Linux 6.11.0-19-generic #19~24.04.1-Ubuntu SMP PREEMPT_DYNAMIC Mon Feb 17 11:51:52 UTC 2 x86_64
Date: Mar 19, 2025

In certain tests, asynchronous communication may exhibit superior performance compared to synchronous communication. This can be attributed to the context-switching performance of libraries such as tokio, which, similar to Golang, utilize context-switching within the same thread to switch to the next coroutine when a message is ready on a channel. This approach is more efficient than communicating between separate threads. This same principle applies to asynchronous network applications, which generally exhibit better performance compared to synchronous implementations. As the channel size increases, one may observe improved performance in synchronous benchmarks, as the sending threads are able to push data directly to the channel queue without requiring awaiting blocking/suspending signals from receiving threads.