簡體   English   中英

Rust 將一堆任務變成在線程池上執行的未來的成語是什么?

[英]What is the Rust idiom for turning a bunch of tasks into futures that are executed on a thread pool?

在 java 中,我將使用一個ExecutorService ,它是一個具有固定大小的線程池,並向其submit(Callable) s,然后get()結果。

Rust中與此匹配的成語是什么? 我可以thread::spawn()一堆任務和join()它們,但它會為每個任務創建一個線程,我想限制並發線程的數量。

為了使事情更具體一些,這里是一些代碼的粗略草圖:

let a4 = thread_pool.spawn(|| svg.compute_stitches("path674"));
let a1 = thread_pool.spawn(|| svg.compute_stitches("path653"));
let a2 = thread_pool.spawn(|| svg.compute_stitches("g659"));
let a3 = thread_pool.spawn(|| svg.compute_stitches("path664"));
let a5 = thread_pool.spawn(|| svg.compute_stitches("path679"));

stitcher.stitch(a1.join());
stitcher.stitch(a2.join());
stitcher.next_color();
stitcher.stitch(a3.join());
stitcher.next_color();
stitcher.stitch(a4.join());
stitcher.next_color();
stitcher.stitch(a5.join());

我暫時推出了自己的解決方案。 它看起來像這樣:

use std::sync::mpsc;
use std::sync::mpsc::{Receiver, RecvError};
use std::{panic, thread};

pub struct ThreadPool {
    channel: spmc::Sender<Mission>,
}

impl ThreadPool {
    pub fn new(thread_count: usize) -> ThreadPool {
        let (tx, rx) = spmc::channel();

        for _ in 0..thread_count {
            let rx2 = rx.clone();
            thread::spawn(move || Self::work_loop(rx2));
        }

        ThreadPool { channel: tx }
    }

    pub fn spawn<F, T: 'static>(&mut self, task: F) -> Answer<T>
    where
        F: FnOnce() -> T + std::panic::UnwindSafe + Send + 'static,
    {
        let (tx, rx) = mpsc::channel();

        let mission = Mission {
            go: Box::new(move || {
                let tmp = panic::catch_unwind(task);
                tx.send(tmp).unwrap()
            }),
        };

        self.channel.send(mission).unwrap();

        Answer { channel: rx }
    }

    fn work_loop(channel: spmc::Receiver<Mission>) {
        while let Ok(mission) = channel.recv() {
            (mission.go)();
        }
    }
}

struct Mission {
    go: Box<dyn FnOnce()>,
}

unsafe impl Send for Mission {}

pub struct Answer<T> {
    channel: Receiver<std::thread::Result<T>>,
}

impl<T> Answer<T> {
    pub fn get(self) -> Result<T, RecvError> {
        let tmp = self.channel.recv();

        match tmp {
            Ok(rval) => match rval {
                Ok(rval) => Ok(rval),
                Err(explosion) => panic::resume_unwind(explosion),
            },
            Err(e) => Err(e),
        }
    }
}

暫無
暫無

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

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