tokio-rs / tokio

A runtime for writing reliable asynchronous applications with Rust. Provides I/O, networking, scheduling, timers, ...
https://tokio.rs
MIT License
25.44k stars 2.3k forks source link

std::thread::sleep blocks another thread even when it's multi thread and multiple workers #6631

Closed takassh closed 3 weeks ago

takassh commented 3 weeks ago

Version

tokio v1.38.0
    ├── bytes v1.6.0
    ├── libc v0.2.155
    ├── mio v0.8.11
    │   └── libc v0.2.155
    ├── num_cpus v1.16.0
    │   └── libc v0.2.155
    ├── parking_lot v0.12.3
    │   ├── lock_api v0.4.12
    │   │   └── scopeguard v1.2.0
    │   │   [build-dependencies]
    │   │   └── autocfg v1.3.0
    │   └── parking_lot_core v0.9.10
    │       ├── cfg-if v1.0.0
    │       ├── libc v0.2.155
    │       └── smallvec v1.13.2
    ├── pin-project-lite v0.2.14
    ├── signal-hook-registry v1.4.2
    │   └── libc v0.2.155
    ├── socket2 v0.5.7
    │   └── libc v0.2.155
    └── tokio-macros v2.3.0 (proc-macro)
        ├── proc-macro2 v1.0.85 (*)
        ├── quote v1.0.36 (*)
        └── syn v2.0.66 (*)

Platform

Darwin Takassh-MacBook-Pro.local 23.3.0 Darwin Kernel Version 23.3.0: Wed Dec 20 21:33:31 PST 2023; root:xnu-10002.81.5~7/RELEASE_ARM64_T8112 arm64

Description Hi thank you for watching this issue. I'm not sure if this is intentional or not but when I run below code, it takes 2 seconds to finish.

use std::time::{Duration, Instant};

#[tokio::main(flavor = "multi_thread", worker_threads = 4)]
async fn main() {
    let start = Instant::now();

    tokio::spawn(async {
        let handle = tokio::spawn(async {
            std::thread::sleep(Duration::from_secs(1));
            println!("task 1 finished")
        });

        std::thread::sleep(Duration::from_secs(1));

        handle.await.unwrap();
    })
    .await
    .unwrap();

    let duration = start.elapsed();
    println!("Time elapsed is: {:?}", duration);
}

On the other hand, when I try this code, it takes 1 second. I just removed outer spawn.

use std::time::{Duration, Instant};

#[tokio::main(flavor = "multi_thread", worker_threads = 4)]
async fn main() {
    let start = Instant::now();

    let handle = tokio::spawn(async {
        std::thread::sleep(Duration::from_secs(1));
        println!("task 1 finished")
    });

    std::thread::sleep(Duration::from_secs(1));

    handle.await.unwrap();

    let duration = start.elapsed();
    println!("Time elapsed is: {:?}", duration);
}

I expected to see the first code is finished around 1 second because std::thread::sleep hangs only current thread. doc says

Puts the current thread to sleep for at least the specified amount of time.

Sorry if I misunderstand anything but if it's bug I thought I should create an issue to heads up.

wathenjiang commented 3 weeks ago

Hi. This issue might be duplicated to https://github.com/tokio-rs/tokio/issues/6491.

Darksonn commented 3 weeks ago

See also #6315.

takassh commented 3 weeks ago

Thank you both!