首页 > 解决方案 > 在线程之间发送 Nalgebra VectorN

问题描述

VectorN<f64, N>在一些运行良好的单线程代码中使用了 Nalgebra 的类型。我现在正在尝试对算法的各个部分进行多线程处理,但是在将VectorNs 传递给thread::spawn调用时遇到了问题。例如,以下代码编译失败:

use std::thread;
use nalgebra::{VectorN, DefaultAllocator, DimName};
use nalgebra::allocator::Allocator;

struct Test<N>
where
    N: DimName,
    DefaultAllocator: Allocator<f64, N>,
{
    pub field: VectorN<f64, N>,
}

impl<N> Test<N>
where
    N: DimName,
    DefaultAllocator: Allocator<f64, N>,
{
    pub fn test(&self) {
        let handle = thread::spawn(move || {
            let thing = self.field;

            let thing2 = thing * 2.0;

            thing2
        });

        let res = handle.join().unwrap();
    }
}

出现此错误:

error[E0277]: `<nalgebra::base::default_allocator::DefaultAllocator as nalgebra::base::allocator::Allocator<f64, N>>::Buffer` cannot be sent between threads safely
  --> trajectories/src/path/mod.rs:34:22
   |
34 |         let handle = thread::spawn(move || {
   |                      ^^^^^^^^^^^^^ `<nalgebra::base::default_allocator::DefaultAllocator as nalgebra::base::allocator::Allocator<f64, N>>::Buffer` cannot be sent between threads safely
   |
   = help: within `nalgebra::base::matrix::Matrix<f64, N, nalgebra::base::dimension::U1, <nalgebra::base::default_allocator::DefaultAllocator as nalgebra::base::allocator::Allocator<f64, N>>::Buffer>`, the trait `std::marker::Send` is not
implemented for `<nalgebra::base::default_allocator::DefaultAllocator as nalgebra::base::allocator::Allocator<f64, N>>::Buffer`
   = note: required because it appears within the type `nalgebra::base::matrix::Matrix<f64, N, nalgebra::base::dimension::U1, <nalgebra::base::default_allocator::DefaultAllocator as nalgebra::base::allocator::Allocator<f64, N>>::Buffer>`
   = note: required by `std::thread::spawn`

我已经在条款中尝试了各种定义N,但还没有走远。各种搜索引擎在这个问题上没有发现任何有用的东西。DefaultAllocatorwhere

如果我替换VectorN<f64, N>VectorN<f64, U3>(或 Nalgebra 中的任何其他U*类型),上述错误就会消失。我已经阅读了Nalgebra 通用编程指南,但这似乎已经过时,也许不是我需要的;我不想要完全的通用性,只想要使用VectorN任何大小限制的能力。我需要在我的结构上放置什么特征界限,以便我可以传递field到线程中?

标签: multithreadingmultidimensional-arrayrustlinear-algebra

解决方案


我在黑暗中刺了一下(基于编译器给出的错误消息)并设法通过添加边界来完成这项工作Allocator::Buffer

use nalgebra::allocator::Allocator;

struct Test<N>
where
    N: DimName,
    DefaultAllocator: Allocator<f64, N>,
    <DefaultAllocator as Allocator<f64, N>>::Buffer: Send + Sync,
{
    pub field: VectorN<f64, N>,
}

// snip ...

我不确定这是不是正确的方法,它肯定会增加一些噪音,但现在似乎让我将 Nalgebra 构造传递给线程。


推荐阅读