簡體   English   中英

如何找到活動的 tokio 任務的數量?

[英]How to find number of active tokio task?

我想獲得正在運行的 tokio 任務的數量。 在 python 中,我可以使用len(asyncio.all_tasks())返回當前運行循環的未完成任務。 我想知道 tokio 中的任何等價物。

這是一個示例代碼:

use std::time::Duration;
use tokio; // 1.24.1
use tokio::time::sleep;

fn active_tasks() -> usize {
    todo!("get active task somehow")
}

#[tokio::main]
async fn main() {
    tokio::spawn(async { sleep(Duration::from_secs(5)).await });
    tokio::spawn(async { sleep(Duration::from_secs(1)).await });
    tokio::spawn(async { sleep(Duration::from_secs(3)).await });

    println!("t = 0, running = {}", active_tasks());

    sleep(Duration::from_secs(2)).await;
    println!("t = 2, running = {}", active_tasks());

    sleep(Duration::from_secs(4)).await;
    println!("t = 6, running = {}", active_tasks());
}

我希望上面程序的 output 打印活動任務的數量,因為 main 本身是一個 tokio 任務,我不會驚訝地發現以下 output:

t = 0, running = 4
t = 2, running = 3
t = 6, running = 1

如果需要, active_tasks()可以是異步 function。

我希望不穩定的RuntimeMetrics能夠為您解決這個問題,但它似乎是為不同的目的而設計的。 我不相信 Tokio 能夠為您處理這件事。

話雖如此,這是實現類似結果的潛在解決方案:

use std::{
    future::Future,
    sync::{Arc, Mutex},
    time::Duration,
};
use tokio::time::sleep;

struct ThreadManager {
    thread_count: Arc<Mutex<usize>>,
}

impl ThreadManager {
    #[must_use]
    fn new() -> Self {
        Self {
            thread_count: Arc::new(Mutex::new(0)),
        }
    }

    fn spawn<T>(&self, future: T)
    where
        T: Future + Send + 'static,
        T::Output: Send + 'static,
    {
        // Increment the internal count just before the thread starts.
        let count = Arc::clone(&self.thread_count);
        *count.lock().unwrap() += 1;

        tokio::spawn(async move {
            let result = future.await;
            
            // Once we've executed the future, let's decrement this thread.
            *count.lock().unwrap() -= 1;

            result
        });
    }

    fn thread_count(&self) -> usize {
        // Get a copy of the current thread count.
        *Arc::clone(&self.thread_count).lock().unwrap()
    }
}

#[tokio::main]
async fn main() {
    let manager = ThreadManager::new();

    manager.spawn(async { sleep(Duration::from_secs(5)).await });
    manager.spawn(async { sleep(Duration::from_secs(1)).await });
    manager.spawn(async { sleep(Duration::from_secs(3)).await });

    println!("t = 0, running = {}", manager.thread_count());

    sleep(Duration::from_secs(2)).await;
    println!("t = 2, running = {}", manager.thread_count());

    sleep(Duration::from_secs(4)).await;
    println!("t = 6, running = {}", manager.thread_count());
}

結果是:

t = 0, running = 3
t = 2, running = 2
t = 6, running = 0

這將大致完成您所描述的內容。 為了更接近您要查找的內容,您可以將管理器與lazy_static結合起來,並將其包裝在名為spawn或其他名稱的 function 中。 您也可以從 1 開始計數器以計算主線程。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM