首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >生成100个线程并递增一个共享计数器,这是否可以优化/改进以在1秒内完成?

生成100个线程并递增一个共享计数器,这是否可以优化/改进以在1秒内完成?
EN

Stack Overflow用户
提问于 2022-09-15 21:54:40
回答 1查看 219关注 0票数 0

我想学习如何用Rust编写这个Go代码,go代码在这里供参考:https://go.dev/play/p/j9osOG5xs1R

它基本上启动100个线程,在每个线程中循环1000次,在每次迭代中休眠1毫秒,并增加一些共享状态。

由于它的睡眠时间为1毫秒,它应该在1秒内完成。

在我的Go版本中,我实际上创建了100个线程,它按照预期在1秒内完成。

我的生锈代码目前只有10个线程,需要10秒才能完成。

我肯定做错了什么,有什么改善性能的建议吗?

代码语言:javascript
运行
复制
use std::sync::{Arc, Mutex};
use std::thread;
use std::time::Duration;

fn main() {
    let counter = Arc::new(Mutex::new(0));
    let mut handles = vec![];

    use std::time::Instant;
    let now = Instant::now();

    for _ in 0..10 {
        let counter = Arc::clone(&counter);
        let handle = thread::spawn(move || {

            let mut num = counter.lock().unwrap();

            for _ in 0..1000 {
                thread::sleep(Duration::from_millis(1));
                *num += 1;
            }
        });
        handles.push(handle);
    }

    for handle in handles {
        handle.join().unwrap();
    }

    println!("Result: {}", *counter.lock().unwrap());

    let elapsed = now.elapsed();
    println!("Elapsed: {:.2?}", elapsed);
}

我甚至在发布模式下构建了这个程序:

代码语言:javascript
运行
复制
cargo build --release
./target/release/spawner

出于某种原因,只有10个线程需要超过10秒.

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-09-15 22:05:10

每个线程在它运行的整个1秒内锁定counter,阻止所有线程取得任何进展。这导致它们按顺序运行,而不是并行运行。

如果你缩小锁的范围,那么他们会每毫秒抓取并释放互斥物,互相解锁,并允许程序在预期的1秒内完成。

代码语言:javascript
运行
复制
let handle = thread::spawn(move || {
    for _ in 0..1000 {
        thread::sleep(Duration::from_millis(1));
        let mut num = counter.lock().unwrap();
        *num += 1;
    }
});

输出:

代码语言:javascript
运行
复制
Result: 10000
Elapsed: 1.09s
票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73737825

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档