大佬帮忙Go 语言并发读写代码的用Rust 实现?

作者站长头像
站长
· 阅读数 16

请大佬帮忙把一段之前golang实现的并发读写代码用rust实现

package main

import (
    "fmt"
    "sync"
    "time"
)

type Rule struct {
    Id    int64
    Words []string
}

type Repo struct {
    Version int64
    rwLock  sync.RWMutex
    Rules   []*Rule
}

func main() {
    r0 := Rule{
        Id:    0,
        Words: []string{"a", "b", "c"},
    }
    r1 := Rule{
        Id:    1,
        Words: []string{"0", "1", "2"},
    }
    repo := Repo{
        Version: 0,
        Rules: []*Rule{
            &r0,
            &r1,
        },
    }

    var wg sync.WaitGroup
    wg.Add(2)

    go func() {
        repo.rwLock.RLock()
        rs := repo.Rules
        repo.rwLock.RUnlock()
        time.Sleep(2 * time.Second)
        for i := range rs {
            fmt.Println(rs[i].Id)
        }
        wg.Done()
    }()

    go func() {
        time.Sleep(1 * time.Second)
        repo.rwLock.Lock()
        repo.Rules[1].Id = 999
        repo.Rules = repo.Rules[0:1]
        repo.Rules[0].Id = 1000
        repo.rwLock.Unlock()
        wg.Done()
    }()

    wg.Wait()
}
回复
1个回答
avatar
test
2024-06-21
use std::sync::{Arc, Mutex};
use std::thread;
use std::time::Duration;

struct Rule {
    id: i64,
    words: Vec<String>,
}

struct Repo {
    version: i64,
    rules: Vec<Arc<Mutex<Rule>>>,
}

fn main() {
    let r0 = Arc::new(Mutex::new(Rule {
        id: 0,
        words: vec!["a".to_string(), "b".to_string(), "c".to_string()],
    }));
    let r1 = Arc::new(Mutex::new(Rule {
        id: 1,
        words: vec!["0".to_string(), "1".to_string(), "2".to_string()],
    }));

    let repo = Arc::new(Repo {
        version: 0,
        rules: vec![r0, r1],
    });

    let mut handles = Vec::new();
    let repo_for_read = Arc::clone(&repo);

    let handle1 = thread::spawn(move || {
        let repo = repo_for_read;
        let rs = repo.rules.clone();
        thread::sleep(Duration::from_secs(2));
        for r in rs.iter() {
            println!("{}", r.lock().unwrap().id);
        }
    });
    handles.push(handle1);

    let repo_for_write = Arc::clone(&repo);
    let handle2 = thread::spawn(move || {
        thread::sleep(Duration::from_secs(1));
        let mut rules = repo_for_write.rules.clone();
        if let Some(r) = rules.get_mut(1) {
            let mut r = r.lock().unwrap();
            r.id = 999;
        }
        rules.remove(1);
        if let Some(r) = rules.get_mut(0) {
            let mut r = r.lock().unwrap();
            r.id = 1000;
        }
    });
    handles.push(handle2);

    for handle in handles {
        handle.join().unwrap();
    }
}
回复
likes
适合作为回答的
  • 经过验证的有效解决办法
  • 自己的经验指引,对解决问题有帮助
  • 遵循 Markdown 语法排版,代码语义正确
不该作为回答的
  • 询问内容细节或回复楼层
  • 与题目无关的内容
  • “赞”“顶”“同问”“看手册”“解决了没”等毫无意义的内容