如果在单核CPU上运行,是否需要互斥/锁

问题描述 投票:0回答:1

我想了解如果我的程序在单核计算机上运行,为什么在 Rust 中使用不安全代码来访问 Rust 中的共享资源/变量是不安全的。 ChatGPT 和 ClaudeAI 都表示这段代码即使在单核计算机上运行也是不安全的:

use std::collections::HashMap;

static mut UNSAFE_MAP: Option<HashMap<u32, u32>> = None;

#[tokio::main(flavor = "current_thread")]
async fn main() {
    // Initialize map
    unsafe { UNSAFE_MAP = Some(HashMap::new()); }

    let task1 = tokio::spawn(async {
        for i in 0..10_000_000u32 {
            unsafe {
                if let Some(map) = &mut UNSAFE_MAP {
                    map.insert(i, i);
                }
            }
        }
    });

    let task2 = tokio::spawn(async {
        for i in 0..10_000_000u32 {
            unsafe {
                if let Some(map) = &mut UNSAFE_MAP {
                    map.insert(i + 10_000_000, i);
                }
            }
        }
    });    

    // Wait for both tasks
    let _ = tokio::join!(task1, task2);

    // Check final state
    unsafe {
        if let Some(map) = &UNSAFE_MAP {
            println!("Final map size: {}", map.len());
            // Should be 20 million if everything worked
        }
    }
}

我了解操作系统可以在任何给定时间停止我的程序。但是,一旦恢复,它应该继续按原定的顺序运行?我还了解到,如果两个 tokio 线程都写入同一个文件或在没有同步/锁的情况下执行任何与操作系统相关的操作,则可能会出现问题。我有一台托管在 AWS 上的单核计算机,我想使用不安全的代码来避免锁定。我实际上正在构建一个 RTP 服务器,所以没有锁会很好。我已经运行这个代码一小时了,但没能让它失败。

这段代码只是我实际程序中的一个示例,我计划有一个指向保存所有共享资源的结构的指针。我大部分时间都会阅读,偶尔也会写入哈希图。由于我正在构建一个 RTP 服务器,即使我使用 RwLock,如果我计划拥有 100 个并发调用,也需要很长时间。

rust rust-tokio unsafe
1个回答
0
投票

我了解操作系统可以在任何给定时间停止我的程序。

它还可以随时更改正在运行的线程。假设您的 Task1 线程正在向映射中插入值,并且刚刚选择要使用的存储桶并验证它未满。然后操作系统决定切换到 Task2 线程,该线程将一个值插入到同一个存储桶中。然后第一个威胁再次开始运行,并覆盖第二个线程插入的值(因为它认为存储桶仍然可用)。

线程抢占比进程抢占更常见不安全。

© www.soinside.com 2019 - 2024. All rights reserved.