Intro to Rust-lang (Concurrency, Threads, Channels, Mutex and Arc)
ฝัง
- เผยแพร่เมื่อ 23 พ.ย. 2024
- In this video, we explore the central mechanisms and concepts of the concurrency model in the Rust programming language. We talk about OS threads, Channels, Mutexs and Arcs and how we can use each to good effect.
Feel free to donate:
BTC: 1ExBSiaEa3pceW98eptJwzR9QHrYZ71Xit
ETH: 0xE448a8DDA5886C49d35B191B2F20630c103024c8
LTC: LXsKxF5JhmMtKgqfcUFdvcXVwiaSqxN9cP
Check out our Twitter: / tensorprogram
Check out our Facebook: / tensor-programming-119...
Check out our Steemit: steemit.com/@t...
Just want to say - THANK YOU for not live coding, and for filling this video full of cuts to the most important information. Too many intro videos on TH-cam have the host live-typing and wasting a lot of time, buit yours wastes none of my time and is full of great info
All of my videos are live coded, I just edit them.
your channel is incredible! great finding I did today! thanks for the quality content!
Glad you are finding my content useful. If you like the Rust stuff, I do have a large series on Rust and WASM coming up some time soon after I finish my work with Dart and Flutter.
Tensor Programming it would be awesome! Really loving the rust stuff. lots of advanced stuff. I already program in python and react/typescript. Your Dart/flutter series are being usefull too for comparison. I will watch the elm stuff too... very curious about it. keep going and thank you!
Right on, the plan is to continue to produce good content, mainly moving towards Scala and Reason as my next technologies and revisiting Elm, Go, Rust and a few others as well going forward.
I got stuck while developing a program and the error code was always related to moved values, now after I watched this video It worked, THANKS A LOT
Thanks you sir, enjoyable video for begginer in Rust
great content! would be great to have a link to a github repo with all that good stuff!
This content did not get its own repo; so unfortunately, that isn't really possible. In future videos, I did make sure to make repos no matter how little code was contained in the tutorial. Many of these concepts will be revisited soon in some form with Async Await and that will have its own repo.
I realize I'm kinda randomly asking but does anybody know of a good site to watch new tv shows online?
Great content!
well prepared presentation and really helpful
Thank you, I am glad you found it helpful and useful. Admittedly it wasn't prepared, it was live coded.
Thank you for this. Just to clarify the principle of the last example with prime numbers:
- so I spawn one thread that keeps spitting out numbers from 100mil up, one by one
- and I spawn 5 threads that keep taking over the mutex from one another, if they get hold of it, they try to listen to the incoming number, they write it to the mutex, then release the mutex, and then check if the number is prime or not?
Why do you use threads for this? Is it because the is_prime function is the expensive one?
Thank you!
Yes it is expensive. That said, obviously this is just an example to show the concurrency options in rust.
Beginner at Rust here - why did you choose to go with sync_channel as opposed to channel? When would you choose one over the other?
sync_channel is synchronous where as channel is asynchronous. I did that because I wanted it to maintain its original order.
@@TensorProgramming Thanks! I guess that's why you need a buffer size? Does that mean there is more than one transmitted value stored up in the buffer ready to be scooped up by the line of receivers?
@@HesperusSays On Sync_channel the buffer will block once it fills up with values so it makes sense to have a large one for this type of example. And yes, more than one transmitted value is stored up in the buffer. They will be scooped up in order however.
Thank you for this awesome video, i just found this, but i have a question.
Is the lock() call on the shared receiver really necessary inside the worker function?
As far as I understand (and admittedly I am not too proficient), a copy of the receiver gets moved into each thread.
Why is there a need to lock access to that memory?
Oh i think i now understand whats happening, the clone doesnt copy the receiver, but rather the smart pointer that points towards it, and since we are in rust we have to clone that explicitly
@@exolicious1416 Exactly. Its not a deep clone, it only takes the pointer.
great tutorial, very clear with easy to follow examples! On a slightly unrelated note how do I get this kind of syntax highlighting and formatting that you're using in VSCode?
The syntax highlighting and formatting is just from the rust extension. Just using rustfmt and the rls (rust language server). the extension is just called rust-lang.rust.
You deserve 1mil+ subs
Haha, yeah dunno about that.
great video! would be nice to hace your code in github as reference to play with
For the intro videos, I chose not to keep the code (admittedly not a great decision). All of my other videos include the code in the description.
Quick, concise video! Also, I'm pretty certain you're Norm McDonald.
I wish, because that would make me rich. Anyhow, cheers mate.
Very Helpful!
I think that move closure decorator concept is silly. Having the thread needing to take a closure to call later within itself is the only reason it's necessary, whereas for example in Go, because you just "mark" a regular closure declaration and call as being another thread, you're able to just pass by value the params which you want the thread to have singular access to, without depriving the main thread from continued separate access of those. What if you want to pass the same list with different index ranges to work on from the list to multiple thread runs? I mean that's an extreme case example, since that's a bad design decision anyway, but yeah, it just sounds really complicated.
Its not as complicated as it seems at first. The main reason why this is even necessary is because of the ownership model where as with Go you have the GC and the runtime, Rust chooses not to have either (or at least minimal versions that you can alter). Just keep in mind that in Rust, you can only have a single mutable reference to some value; and obviously there is some inherent complexity to trying to apply that rule to asynchronous and multithreaded applications.
All the move keyword is really doing is capturing ownership of the vector v in this case or of any potential values that are being used by the closure. Remember, Vectors in Rust are smart pointers by definition, so they need to be moved into the scope of the closure or else there would be no guarantee that the memory addresses would still contain data when the closure runs.
Part of this leads into why there are multiple different closure types that you can use in Rust. Youve got FnOnce, Fn and FnMut and they each capture and use their values differently. FnOnce will consume the captured variables and it must take ownership of these variables to do so, FnMut can change the environment because it mutably borrows the values and Fn borrows the values immutably. Basically when you add move to any of these traits, you force the closure to take ownership of the values it uses for its environment.
As an aside, I don't especially like the way that Closures are implemented in Rust (I am generally more of a functional programmer), but I also understand why it was necessary to implement them in such a way.
what if i want to stop generating numbers in producer fn when i reaches 200_000_000. i guess i would need to rewrite worker fn to be able to break from loop. any idea how?
you'd just need to add an if statement on n in the worker function and break from there.
So channels is like pipes in C?
Sort of but they have some fairly large differences built into them. From a functionality standpoint they are more similar to messages in Actors then to the Pipes in C (though they are lower level then your traditional actor message). You've got guards which protect you from data races with channels which don't exist in Pipes.
Or gas station bathroom key - that's what I think of.
Hmm yeah perhaps.