Tokio channel deadlock

I faced some interesting behavior using tokio's channel - tokio::sync::mpsc .

Long story short: in some cases, receiver doesn't get the value, sent by the sender if there's something like loop (or any other heavy computations, i assume?) on the current tokio-thread.

Channel from std::thread::sync works perfectly though. I assume it has something to do with either tokio scheduler or cpu context switch ?

Even in the example below it works correctly from time to time. But sometimes it prints "second thread" only when the first thread is dead due to integer overflow.

How can i overcome this problem ? For now i use default channel() from std::thread::sync . But it seems like a crutch to me.


use tokio::sync::mpsc;

async fn thread1(mut sender: mpsc::Sender<bool>) {
    let mut i = 0;
    loop {
        i += 1;
        if i == 100 {

async fn thread2(mut receiver: mpsc::Receiver<bool>) {
    println!("second  thread");

async fn main() {
    let (sender, receiver) = mpsc::channel(1);

    let p1 = tokio::spawn(async move {

    let p2 = tokio::spawn(async move {

    tokio::join!(p1, p2);

Thanks in advance!

This kind of question is more appropriate in the forum.

Excuse me!

To elaborate, this forum is more focused around the compiler and the language design. The “users” forum is where lots of help threads are and also all the people who are good at helping out, so feel free to copy your post verbatim to over there. Nontheless, welcome to this forum, too!