Multithreading 我如何总结使用并发性从1到1000000的情况?

Multithreading 我如何总结使用并发性从1到1000000的情况?,multithreading,concurrency,parallel-processing,rust,Multithreading,Concurrency,Parallel Processing,Rust,我是一个新手生锈,我想总结大量的数字使用并发。我发现这个代码: use std::thread; use std::sync::{Arc, Mutex}; static NTHREAD: usize = 10; fn main() { let mut threads = Vec::new(); let x = 0; // A thread-safe, sharable mutex object let data = Arc::new(Mutex::new(

我是一个新手生锈,我想总结大量的数字使用并发。我发现这个代码:

use std::thread;
use std::sync::{Arc, Mutex};

static NTHREAD: usize = 10;

fn main() {
    let mut threads = Vec::new();

    let x = 0;

    // A thread-safe, sharable mutex object
    let data = Arc::new(Mutex::new(x));

    for i in 1..(NTHREAD+1) {
        // Increment the count of the mutex
        let mutex = data.clone();

        threads.push(thread::spawn(move || {
            // Lock the mutex
            let n = mutex.lock();

            match n {
                Ok(mut n) => *n += i,
                Err(str) => println!("{}", str)
            }
        }));
    }

    // Wait all threads ending
    for thread in threads {
        let _ = thread.join().unwrap();
    }

    assert_eq!(*data.lock().unwrap(), 55);
}
这在线程数为10时起作用,但在线程数大于20时不起作用

我认为它应该在任何数量的线程


我误解了什么吗?有没有其他方法可以将并发性从1总结到1000000?

提供的代码有几个问题

  • thread::spawn
    创建操作系统级线程,这意味着现有代码不可能扩展到标题中所示的一百万。这需要一百万个并行线程,而典型的现代操作系统最多只能支持几千个线程。更受约束的环境,如嵌入式系统或虚拟机/准虚拟机,允许远低于此;例如,似乎允许最多24个并发线程。相反,我们需要创建一个固定的少量线程,并仔细地在它们之间分配工作
  • 在每个线程中执行的函数在锁中运行,锁有效地序列化线程完成的工作。即使可以生成任意多个线程,所编写的循环执行速度也不会比单个线程快——实际上,它的执行速度要慢几个数量级,因为它会花费大量时间锁定/解锁竞争激烈的互斥锁
  • 中提供了一种在仍然手动管理线程的情况下解决此类问题的好方法:如果有4个线程,只需对每个线程中的1..250k、250k..500k等求和,然后对线程函数的返回求和

    或者有没有其他方法可以在并发情况下从1汇总到1000000

    我建议使用一个更高级的库来封装工作线程的创建/池以及它们之间的工作分工。是一个很好的工具,提供了一个“并行迭代”工具,它的工作方式类似于迭代,但会自动在多个核心之间划分工作。使用人造丝,整数的并行求和如下所示:

    extern crate rayon;
    
    use rayon::prelude::*;
    
    fn main() {
        let sum: usize = (1..1000001).collect::<Vec<_>>().par_iter().sum();
        assert_eq!(sum, 500000500000);
    }
    
    extern板条箱人造丝;
    使用人造丝::前奏::*;
    fn main(){
    让sum:usize=(1..1000001).collect::().par_iter().sum();
    资产(总额500000500000);
    }
    
    提供的代码有几个问题

  • thread::spawn
    创建操作系统级线程,这意味着现有代码不可能扩展到标题中所示的一百万。这需要一百万个并行线程,而典型的现代操作系统最多只能支持几千个线程。更受约束的环境,如嵌入式系统或虚拟机/准虚拟机,允许远低于此;例如,似乎允许最多24个并发线程。相反,我们需要创建一个固定的少量线程,并仔细地在它们之间分配工作
  • 在每个线程中执行的函数在锁中运行,锁有效地序列化线程完成的工作。即使可以生成任意多个线程,所编写的循环执行速度也不会比单个线程快——实际上,它的执行速度要慢几个数量级,因为它会花费大量时间锁定/解锁竞争激烈的互斥锁
  • 中提供了一种在仍然手动管理线程的情况下解决此类问题的好方法:如果有4个线程,只需对每个线程中的1..250k、250k..500k等求和,然后对线程函数的返回求和

    或者有没有其他方法可以在并发情况下从1汇总到1000000

    我建议使用一个更高级的库来封装工作线程的创建/池以及它们之间的工作分工。是一个很好的工具,提供了一个“并行迭代”工具,它的工作方式类似于迭代,但会自动在多个核心之间划分工作。使用人造丝,整数的并行求和如下所示:

    extern crate rayon;
    
    use rayon::prelude::*;
    
    fn main() {
        let sum: usize = (1..1000001).collect::<Vec<_>>().par_iter().sum();
        assert_eq!(sum, 500000500000);
    }
    
    extern板条箱人造丝;
    使用人造丝::前奏::*;
    fn main(){
    让sum:usize=(1..1000001).collect::().par_iter().sum();
    资产(总额500000500000);
    }
    
    对于您的特定示例,如果您有4个线程,只需对每个线程中的
    1..250k
    250k..500k
    等进行求和,然后对线程函数的返回进行求和。你必须记住,并行计算的每一种情况都是独一无二的,一切都取决于你的问题。“但是当线程超过20个时就不能工作”当线程超过20个时会发生什么?这些细节不值得忽略。我认为OP说他不能在台式计算机中生成1M个线程。对于您的特定示例,如果您有4个线程,只需对每个线程中的
    1..250k
    250k..500k
    等求和,然后对线程函数的返回求和。你必须记住,并行计算的每一种情况都是独一无二的,一切都取决于你的问题。“但是当线程超过20个时就不能工作”当线程超过20个时会发生什么?这些细节不值得忽略。我认为OP说他不能在台式计算机中产生一百万个线程。游戏场在Docker容器中执行代码,但我认为对线程数量没有任何额外限制。你是如何测试得出24的?为了指出这个问题的愚蠢之处,对从零到
    n
    的数字范围求和的正确方法是
    sum(n)=(n*(n+1))/2
    @Shepmaster I tested copy将OP的代码粘贴到操场上,并对
    unwrap()的最小线程数进行二进制搜索
    失败,并显示与资源相关的错误消息。在我的测试中,它失败了,增加了23个线程,这让我得出结论,虚拟机中总共允许24个线程。我同意这个问题的愚蠢,从字面上理解。答案假设实际意图是执行som