Skip to content

Commit

Permalink
add
Browse files Browse the repository at this point in the history
  • Loading branch information
szabgab committed Jul 18, 2024
1 parent d85c2f8 commit 95c5c43
Show file tree
Hide file tree
Showing 9 changed files with 98 additions and 28 deletions.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
[package]
name = "simple"
version = "0.1.0"
edition = "2021"

[dependencies]
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Before starting: ThreadId(1)
In thread ThreadId(2)
After ending: ThreadId(1)
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
use std::thread;

fn main() {
println!("Before starting: {:?}", thread::current().id());

thread::spawn(|| {
println!("In thread {:?}", thread::current().id());
for i in 1..10000000 {
let _n = i + i;
}

});

for i in 1..10000000 {
let _n = i + i;
}

println!("After ending: {:?}", thread::current().id());
}
22 changes: 22 additions & 0 deletions slides/rust/examples/threads/speed-test/out.out
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
multiple threads
spawned ThreadId(2) finished
spawned ThreadId(4) finished
spawned ThreadId(3) finished
spawned ThreadId(5) finished
spawned ThreadId(7) finished
spawned ThreadId(8) finished
spawned ThreadId(6) finished
spawned ThreadId(9) finished
Received: 10946
Received: 10946
Received: 10946
Received: 10946
Received: 10946
Received: 10946
Received: 10946
Received: 10946
spawned ThreadId(10) finished
Received: 10946
spawned ThreadId(11) finished
Received: 10946
Time elapsed in expensive_function() is: 1.851333ms
21 changes: 10 additions & 11 deletions slides/rust/examples/threads/speed-test/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
use std::time::Instant;
use std::sync::mpsc;
use std::thread;
use std::env;
use std::process;
use std::sync::mpsc;
use std::thread;
use std::time::Instant;

fn main() {
let args = env::args().collect::<Vec<String>>();
if args.len() != 3 {
eprintln!("Usage: {} n [linear|threads]", args[0]);
process::exit(1);
}
let n = args[1].parse::<u64>().expect(format!("Could not convert {} to integer", args[1]).as_str());
let n = args[1]
.parse::<u64>()
.expect(format!("Could not convert {} to integer", args[1]).as_str());

let repetition = 10;

Expand All @@ -19,18 +21,15 @@ fn main() {
linear(n, repetition);
} else if args[2] == "threads" {
in_threads(n, repetition);

} else {
println!("Invalid parameter {}", args[2])
}


let duration = start.elapsed();
println!("Time elapsed in expensive_function() is: {:?}", duration);

}

fn fibonacci(n :u64) -> u64 {
fn fibonacci(n: u64) -> u64 {
if n == 0 || n == 1 {
return 1;
}
Expand All @@ -53,12 +52,12 @@ fn in_threads(n: u64, repetition: i32) {
thread::spawn(move || {
let res = fibonacci(n);
txr.send(res.to_string()).unwrap();
println!("spawned thread finished");
println!("spawned {:?} finished", thread::current().id());
});
}
drop(tx); // need to drop in the main thread

for received in rx {
println!("Got: {}", received);
}
println!("Received: {}", received);
}
}
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
ThreadId(1): start
Got: ThreadId(2): 1
Got: ThreadId(3): 1
Got: ThreadId(3): 2
Got: ThreadId(2): 2
Got: ThreadId(3): 3
Got: ThreadId(2): 3
Got: ThreadId(2): 4
Got: ThreadId(3): 4
Received: ThreadId(2): 1
Received: ThreadId(3): 1
Received: ThreadId(2): 2
Received: ThreadId(3): 2
Received: ThreadId(2): 3
Received: ThreadId(3): 3
Received: ThreadId(2): 4
Received: ThreadId(3): 4
Spawned thread ThreadId(2) ends
Received: ThreadId(2): 5
Spawned thread ThreadId(3) ends
Got: ThreadId(2): 5
Got: ThreadId(3): 5
Received: ThreadId(3): 5
Main thread ends
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ fn main() {
});

for received in rx {
println!("Got: {}", received);
println!("Received: {received}");
}

println!("Main thread ends");
Expand Down
26 changes: 20 additions & 6 deletions slides/rust/threads.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,22 @@
* [Feerless concurrency](https://doc.rust-lang.org/book/ch16-00-concurrency.html) (The Rust book)
* [std::thread](https://doc.rust-lang.org/std/thread/)

## Simple thread (with fake work)
{id: thread-simple-with-fake-work}

* We can easily start a new thread using the [spawn](https://doc.rust-lang.org/std/thread/fn.spawn.html) function of the [thread](https://doc.rust-lang.org/std/thread/) crate.
* We even have two loops one in the main thread and one in the created thread to "do some work". It seems to work.
* There is a slight problem though. Our main program might end before the thread can do the actual work and this example we don't even see that.

![](examples/threads/simple-while-main-is-working/src/main.rs)
![](examples/threads/simple-while-main-is-working/out.out)

## Simple thread
{id: thread-simple}
{i: thread}
{i: spawn}

* We can easily start a new thread using the [spawn](https://doc.rust-lang.org/std/thread/fn.spawn.html) function of the [thread](https://doc.rust-lang.org/std/thread/) crate.
* There is a slight problem though. Our main program might end before the thread can do anything.
* In this case when the main thread does not do "extra job" it is obvious that the other thread did not even have a chance to start working.

![](examples/threads/simple/src/main.rs)
![](examples/threads/simple/out.out)
Expand All @@ -25,12 +33,14 @@
{i: spawn}
{i: join}

* The solution is to save the `handle` of the thread and the use `join` to wait for its termination.

![](examples/threads/simple-with-join/src/main.rs)
![](examples/threads/simple-with-join/out.out)


## First example with threads
{id: threads-first-example}
## Show that threads work in parallel
{id: threads-work-in-parallel}
{i: thread}
{i: spawn}
{i: sleep}
Expand All @@ -51,10 +61,13 @@
{i: recv}
{i: move}

* We can faciliate communication between the main thread and the spawned thread.
* We can facilitate communication between the main thread and the spawned thread.
* In this example the spawned thread is sending a message to the main thread.
* The `move` keyword tells Rust that the variables declared before spawning that are also used in the spawned code need to be moved. (`tx` in this case)
* `recv` is blocking the main thread.
* We can use `recv`, which is blocking the main thread, to wait for a message from the spwaned thread.
* In that case we will have to know how many messages to expect and if we are still waiting for a message while the spawened thread exits then we either get stuck or get panic!.
* Using the second loop is a better solution.


![](examples/threads/threads-messages/src/main.rs)
![](examples/threads/threads-messages/out.out)
Expand Down Expand Up @@ -87,6 +100,7 @@ N single multi
```

![](examples/threads/speed-test/src/main.rs)
![](examples/threads/speed-test/out.out)


## Save many files (both CPU and IO intensive)
Expand Down

0 comments on commit 95c5c43

Please sign in to comment.