initial commit

This commit is contained in:
2024-06-23 02:38:20 -04:00
commit de720e326d
136 changed files with 4533 additions and 0 deletions

9
threads/README.md Normal file
View File

@@ -0,0 +1,9 @@
# Threads
In most current operating systems, an executed program's code is run in a process, and the operating system manages multiple processes at once.
Within your program, you can also have independent parts that run simultaneously. The features that run these independent parts are called threads.
## Further information
- [Dining Philosophers example](https://doc.rust-lang.org/1.4.0/book/dining-philosophers.html)
- [Using Threads to Run Code Simultaneously](https://doc.rust-lang.org/book/ch16-01-threads.html)

40
threads/threads1.rs Normal file
View File

@@ -0,0 +1,40 @@
// threads1.rs
//
// This program spawns multiple threads that each run for at least 250ms, and
// each thread returns how much time they took to complete. The program should
// wait until all the spawned threads have finished and should collect their
// return values into a vector.
//
// Execute `rustlings hint threads1` or use the `hint` watch subcommand for a
// hint.
// I AM DONE
use std::thread;
use std::time::{Duration, Instant};
fn main() {
let mut handles = vec![];
for i in 0..10 {
handles.push(thread::spawn(move || {
let start = Instant::now();
thread::sleep(Duration::from_millis(250));
println!("thread {} is complete", i);
start.elapsed().as_millis()
}));
}
let mut results: Vec<u128> = vec![];
for handle in handles {
results.push(handle.join().unwrap());
}
if results.len() != 10 {
panic!("Oh no! All the spawned threads did not finish!");
}
println!();
for (i, result) in results.into_iter().enumerate() {
println!("thread {} took {}ms", i, result);
}
}

43
threads/threads2.rs Normal file
View File

@@ -0,0 +1,43 @@
// threads2.rs
//
// Building on the last exercise, we want all of the threads to complete their
// work but this time the spawned threads need to be in charge of updating a
// shared value: JobStatus.jobs_completed
//
// Execute `rustlings hint threads2` or use the `hint` watch subcommand for a
// hint.
// I AM DONE
use std::sync::{Arc, Mutex};
use std::thread;
use std::time::Duration;
struct JobStatus {
jobs_completed: u32,
}
fn main() {
let status = Arc::new(Mutex::new(JobStatus { jobs_completed: 0 }));
let mut handles = vec![];
for _ in 0..10 {
let status_shared = Arc::clone(&status);
let handle = thread::spawn(move || {
thread::sleep(Duration::from_millis(250));
// TODO: You must take an action before you update a shared value
status_shared.lock().unwrap().jobs_completed += 1;
});
handles.push(handle);
}
for handle in handles {
handle.join().unwrap();
// TODO: Print the value of the JobStatus.jobs_completed. Did you notice
// anything interesting in the output? Do you have to 'join' on all the
// handles?
println!("jobs completed {}", status.lock().unwrap().jobs_completed)
}
}

74
threads/threads3.rs Normal file
View File

@@ -0,0 +1,74 @@
// threads3.rs
//
// Execute `rustlings hint threads3` or use the `hint` watch subcommand for a
// hint.
// I AM DONE
use std::sync::mpsc;
use std::sync::Arc;
use std::thread;
use std::time::Duration;
struct Queue {
length: u32,
first_half: Vec<u32>,
second_half: Vec<u32>,
}
impl Queue {
fn new() -> Self {
Queue {
length: 10,
first_half: vec![1, 2, 3, 4, 5],
second_half: vec![6, 7, 8, 9, 10],
}
}
}
fn send_tx(q: Queue, tx: mpsc::Sender<u32>) -> () {
let qc = Arc::new(q);
let qc1 = Arc::clone(&qc);
let qc2 = Arc::clone(&qc);
let tx_cloned = tx.clone();
thread::spawn(move || {
for val in &qc1.first_half {
println!("sending {:?}", val);
tx_cloned.send(*val).unwrap();
thread::sleep(Duration::from_secs(1));
}
});
thread::spawn(move || {
for val in &qc2.second_half {
println!("sending {:?}", val);
tx.send(*val).unwrap();
thread::sleep(Duration::from_secs(1));
}
});
}
#[test]
fn main() {
let (tx, rx) = mpsc::channel();
let queue = Queue::new();
let queue_length = queue.length;
send_tx(queue, tx);
let mut total_received: u32 = 0;
for received in rx {
println!("Got: {}", received);
total_received += 1;
}
println!("total numbers received: {}", total_received);
assert_eq!(total_received, queue_length)
}