Rust 并行库 crossbeam 的 Channel 示例

下面是一个完整的示例程序:

rust 复制代码
use crossbeam::channel;
use crossbeam::thread;
use std::thread::sleep;
use std::time::Duration;

// 定义Task结构体
struct Task {
    data: usize, // 假设任务包含一个数据字段
    call_box: Box<dyn FnMut()>, // 假设任务包含一个可调用对象的装箱指针
}

impl Task {
    fn new(data: usize, call_box: impl FnMut() + 'static) -> Self {
        Task {
            data,
            call_box: Box::new(call_box),
        }
    }

    // 实现call_box方法
    fn call_box(&mut self) {
        (self.call_box)();
    }
}

fn main() {
    const NUMBER_OF_WORKERS: usize = 4; // 假设有4个工作线程
    let (tx, rx) = channel::unbounded::<Task>();
    let mut handlers = vec![];

    // 启动工作线程
    for _ in 0..NUMBER_OF_WORKERS {
        let rx = rx.clone();
        let handle = thread::spawn(move || {
            while let Some(task) = rx.recv() {
                task.call_box(); // 执行任务
            }
        });
        handlers.push(handle);
    }

    // 发送任务到通道
    for i in 0..10 { // 假设发送10个任务
        let task = Task::new(i, || {
            println!("Executing task with data: {}", i);
            sleep(Duration::from_secs(1)); // 模拟耗时操作
            println!("Finished task with data: {}", i);
        });
        tx.send(task).unwrap();
    }

    // 关闭发送通道
    drop(tx);

    // 等待所有工作线程完成
    for handle in handlers {
        handle.join().unwrap();
    }

    println!("All tasks are processed.");
}

在这个程序中,我们定义了一个Task结构体,它包含一个data字段和一个call_box字段,后者是一个装箱的可调用对象。我们实现了call_box方法,它调用这个装箱的可调用对象。

在main函数中,我们创建了一个无界通道,用于在工作线程和主线程之间传递Task实例。我们启动了NUMBER_OF_WORKERS个工作线程,它们不断地从通道接收Task实例并调用call_box方法执行它们。

然后,主线程创建了一些Task实例,并通过通道发送它们给工作线程。一旦所有任务都被发送,主线程通过drop(tx)关闭了发送通道,这样工作线程在尝试接收任务时,如果没有更多任务可用,将会得到一个None,从而退出循环。

最后,主线程等待所有工作线程完成,并打印出消息表示所有任务都已经处理完毕。

请注意,为了简化示例,我使用了Box<dyn FnMut()>来允许Task存储任何可调用对象的装箱指针。这意味着任务中的可调用对象必须能够单独编译成一个独立的、无状态的函数,这样才能安全地在多个线程之间共享。在实际应用中,你可能需要根据你的具体需求调整Task结构体的设计和使用方式。

相关推荐
酷炫码神4 小时前
Day 10|Pinia 状态管理:把散落在各组件的数据,收进一个全局仓库
android·开发语言·javascript
Elastic 中国社区官方博客5 小时前
我们如何通过 70 多个拉取请求,将 OpenTelemetry Java agent 迁移到 invokedynamic
java·大数据·开发语言·elasticsearch·搜索引擎·全文检索·es
tyn1885 小时前
记录本地安装nacos服务的方法及异常
java·开发语言
步行cgn6 小时前
Spring MVC 视图机制的核心接口与类
java·开发语言·后端·spring·mvc
传奇开心果编程7 小时前
【Rust入门练中学】第5课:引用与借用
开发语言·rust·引用·编程语言理论·通用编程语言·借用
qetfw7 小时前
Bash 变量:export、位置参数与默认值展开验证
linux·开发语言·chrome·bash
电子云与长程纠缠7 小时前
UE5魂系游戏开发教程05
开发语言·学习·游戏·ui·ue5
cspttty7 小时前
2027风险管理岗准备路线:数学与应用数学如何补齐金融、SQL与Python
开发语言·python·金融
我命由我123457 小时前
Python 开发 - Python 的 pathlib
java·开发语言·后端·python·学习·java-ee·学习方法
严谨的麻辣烫8 小时前
Python HTTP 连接池怎么用?从连接复用到请求异常排查
开发语言·python·http·requests·网络排查