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()
}
use std::sync::{Mutex, RwLock, Arc};
use std::time::Duration;
use std::thread;
struct Rule {
id: i64,
words: Vec<String>,
}
struct Repo {
version: i64,
rw_lock: Arc<RwLock<Rule>>,
rules: Vec<Rule>,
}
impl Repo {
fn new(version: i64) -> Repo {
let rules = vec![Rule {
id: 0,
words: vec![String::from("a"), String::from("b"), String::from("c")],
}, Rule {
id: 1,
words: vec![String::from("0"), String::from("1"), String::from("2")],
}];
Repo {
version,
rw_lock: Arc::new(RwLock::new(rules[0])),
rules,
}
}
}
fn main() {
let repo = Repo::new(0);
let repo_clone = repo.clone(); // For read access in the first goroutine.
let repo_clone2 = repo.clone(); // For write access in the second goroutine.
let wg = Arc::new(Mutex::new(0)); // Use a mutex for WaitGroup.
let wg2 = wg.clone(); // For each goroutine.
thread::spawn(move || {
let mut wg = wg2.lock().unwrap();
*wg += 1; // Wait for the second goroutine to start.
let rule = repo_clone.rw_lock.read().unwrap(); // Read-lock for read access.
println!("{:?}", rule.id); // Print the ID of the first rule.
thread::sleep(Duration::from_secs(2)); // Sleep for 2 seconds.
for rule in &repo_clone.rules { // Print the IDs of all rules.
println!("{:?}", rule.id);
}
*wg -= 1; // Signal the WaitGroup that this goroutine is done.
});
thread::spawn(move || {
let mut wg = wg2.lock().unwrap(); // Wait for the first goroutine to start.
*wg += 1; // Signal the WaitGroup that this goroutine has started.
{ // Write-lock for write access.
let mut repo = repo_clone2.rw_lock.write().unwrap(); // Write-lock for write access.
repo.id = 999; // Modify the ID of the second rule.
repo.rules = repo.rules[0..1].to_vec(); // Remove all rules except the first one.
repo.id = 1000; // Modify the ID of the first rule.
} // Unlock after modifying the rules.
*wg -= 1; // Signal the WaitGroup that this goroutine is done.
});
thread::park_timeout(Duration::from_secs(3)); // Wait for both goroutines to finish.
}
以上答案由文心大模型3.5生成