首页 > 解决方案 > 如何在后台运行工作负载?

问题描述

我有一个基于循环的 GUI 应用程序。循环可以比每一帧更频繁地运行,因此它需要是轻量级的。不时需要完成繁重的工作量。我不确定如何实现。我在想像:

extern crate tokio; // 0.1.7
extern crate tokio_threadpool; // 0.1.2

use std::{thread, time::Duration};
use tokio::{prelude::*, runtime::Runtime};

fn delay_for(
    seconds: u64
    ) -> impl Future<Item = u64, Error = tokio_threadpool::BlockingError> 
{
    future::poll_fn(move || {
        tokio_threadpool::blocking(|| {
            thread::sleep(Duration::from_secs(seconds));
            seconds
        })
    })
}

fn render_frame(n: i8) {
    println!("rendering frame {}", n);
    thread::sleep(Duration::from_millis(500));
}

fn send_processed_data_to_gui(n: i8) {
    println!("view updated. result of background processing was {}", n);
}

fn main() {
    let mut frame_n = 0;
    let frame_where_some_input_triggers_heavy_work = 2;
    let mut parallel_work: Option<BoxedFuture> = None;
    loop {
        render_frame(frame_n);
        if frame_n == frame_where_some_input_triggers_heavy_work {
            parallel_work = Some(execute_in_background(delay_for(1)));
        }

        // check if there's parallel processing going on
        // and handle result if it's finished
        parallel_work
            .take()
            .map(|parallel_work| {
                if parallel_work.done() {
                    // giving result back to app
                    send_processed_data_to_gui(parallel_work.result())
                }
            });

        frame_n += 1;
        if frame_n == 10 {
            break;
        }
    }
}

fn execute_in_background(work: /* ... */) -> BoxedFuture {
    unimplemented!()
}

游乐场链接

以上示例基于链接答案的 tokio-threadpool 示例。该示例具有如下数据流:

let a = delay_for(3);
let b = delay_for(1);
let sum = a.join(b).map(|(a, b)| a + b); 

该示例与我的案例之间的主要区别在于,任务a触发任务b,完成时b获得a传递结果b并继续工作。它也将重复此任意次数。

我觉得我正在尝试以一种不是 Rust 中惯用的异步编程的方式来解决这个问题。

如何在后台运行该工作负载?或者按照上面的代码草图重新表述:我如何parallel_work并行执行未来?如果我的方法确实严重偏离了轨道,你能把我推向正确的方向吗?

标签: parallel-processingrust

解决方案


推荐阅读