Crust of Rust: Send, Sync, and their implementors

  Рет қаралды 41,619

Jon Gjengset

Jon Gjengset

Күн бұрын

This time we go over the Send and Sync marker traits from the standard library, as well as some of the most important implementors (and non-implementors) of them. You can find the nomicon entry for Send/Sync here: doc.rust-lang.org/nomicon/sen....
Live version with chat: • Crust of Rust: Send, S...
0:00:00 Why Send and Sync?
0:01:31 What are Send and Sync?
0:02:51 Marker traits
0:03:50 Auto traits
0:05:45 The Send trait
0:06:49 Types that aren't Send
0:09:40 Digging into Rc
0:23:52 The Sync trait
0:26:21 Send + !Sync
0:32:41 Negative implementations
0:35:17 Sending mutable references
0:37:00 Raw pointers
0:41:54 std::sync::mpsc and !Sync
0:42:30 Placement of T: Send/Sync bounds
0:46:04 Per-OS impl Send for guards
0:47:06 more std::sync::mpsc and !Sync
0:48:40 Is Send/Sync auto-implemented?
0:50:40 The nomicon Send/Sync entry
0:52:57 There's no magic!
1:02:46 Negative impls on stable

Пікірлер: 39
@Kaiwa1234
@Kaiwa1234 2 жыл бұрын
I looked at the channel yesterday and was sad to see no new videos for 3 months. Just now I wake up to a new video notification. Today is a good day!
@nataliagoc916
@nataliagoc916 2 жыл бұрын
It was the same for me but first I found out about a new video through Reddit which doubled the effect of a happy surprise
@japedr
@japedr 2 жыл бұрын
Thanks a lot! I feel that for this particular topic there was no clear explanation for us who didn't understand the design decisions beforehand. Ok, just to check that I got it all right, I understand that we can have: - Send + Sync: applies to "most" types, no restrictions. - !Send + Sync: cross-thread transfer of ownership is not fine, but transfer of a &-reference is fine. Other threads can access the value but are not allowed to drop it, nor &mut-modify it. Prototypical example: lock guards (like MutexGuard), "per-thread" allocation via thread_local/TLS (?). - !Send + !Sync: neither owned nor &-reference transfer are sound. This is because there are methods accessible via &-references that break some invariant if called from a different thread. Prototypical example: Rc, it is !Send because of its non-atomic reference counter (can cause a double-free (UB!) or leak (not so serious)), !Sync because clone() also manipulates said counter. Arc is Send + Sync by using atomics (performance tradeoff). Raw pointers are purposefully !Send + !Sync to "contaminate" any enclosing types, just as an extra security measure. - Send + !Sync: weirdest case, this applies when we want to have all references in the same thread as the owning one, but as the same time we want to allow cross-thread ownership transfer. This is the case of interior mutability wrapper types. Prototypical example: {,Ref,Unsafe}Cell.
@jonhoo
@jonhoo 2 жыл бұрын
Yes, that's a good summary!
@fbytgeek
@fbytgeek 2 жыл бұрын
Thank you for your time and effort. Very much appreciated!
@michaelr280
@michaelr280 2 жыл бұрын
Really enjoyed the video. Feel like I understand send and sync better now
@samuel.ibarra
@samuel.ibarra 2 жыл бұрын
Great content, many thanks for all time and effort
@dimitrimitropoulos
@dimitrimitropoulos 2 жыл бұрын
please keep doing crust of rust!! thank you!
@masiarek
@masiarek 2 жыл бұрын
Great video. Thank you very much!
@Brynnyay
@Brynnyay 2 жыл бұрын
You are my hero Jon! Rust for life.
@TeamDman
@TeamDman 3 ай бұрын
Lovely explanation, thank you!
@askii2004
@askii2004 2 жыл бұрын
how can I get notifs for livestreams? these videos are literally the highlight of my KZbin watch history
@beastle9end499
@beastle9end499 2 жыл бұрын
Great video, really interesting to listen to you, keep up the good work!
@karelhrkal8753
@karelhrkal8753 Жыл бұрын
31:50 It's not solely about multithreading that makes mutation from behind a shared reference dangerous. Imagine the data has a Vec, and someone has a direct reference into the Vec (gained by Vec::get()), and you push a new item and it re-allocates the Vec, making that reference point into deallocated memory. I guess that's why Cell doesn't implement Borrow / doesn't allow you to get a shared reference, only to replace the value entirely?
@alexzander__6334
@alexzander__6334 Жыл бұрын
non related question: what is your terminal font? looks really good and readable for coding
@damoon_az2465
@damoon_az2465 2 ай бұрын
Thanks!
@CPTSMONSTER
@CPTSMONSTER Ай бұрын
11:10 T does not have to be Clone in Rc 11:45 If &mut is omitted, the code would still work, as dereferencing a mutable raw pointer (self.inner: *mut Inner) gives mutable access to Inner 13:10 &unsafe { &*self.inner }.value: &* dereferences the raw pointer and casts the Inner to a shared reference, & casts the value to a shared reference 25:30 MutexGuard is Sync + !Send, Rc is !Send (clone Rc and send to another thread, reference count is not atomic) + !Sync (send &Rc to another thread and call clone, requires all access happens on one thread) 28:40 Cell is Send + !Sync, can't get reference to Cell in another thread, therefore safe to mutate in current thread as no other reference is mutating it. T must also implement Send + !Sync. 31:00 Application of Cell in graph traversal (can't take exclusive references, could walk same node), Cell allows mutation through a shared reference 36:20 If &mut T is Send, then T must be Send (std::mem::replace) 45:00 T is Sync because all the Arc instances reference T, T is Send because the last Arc must drop the inner type 46:00 &T is Send if T is Sync 47:30? Sender is !Sync, multiple shared references to Sender but only one in each thread 54:30 dyn syntax allows only one trait, exceptions are auto traits (Send, Sync) 59:50 thread::spawn requires type is 'static & and Send, not Sync as it doesn't take references 1:00:40 thread::scope does not need 'static & arguments, current thread can't return until scoped thread joined
@hapashreguiem7460
@hapashreguiem7460 2 жыл бұрын
Can you make video about std::any
@antoniocorbibellot6532
@antoniocorbibellot6532 2 жыл бұрын
Coming to Spain this summer? 😃
@NKBrick
@NKBrick 2 жыл бұрын
great vid! could you please share your vim plugins?
@jonathanbishop4437
@jonathanbishop4437 2 жыл бұрын
Yessss
@user-hj3oh3to9j
@user-hj3oh3to9j 9 ай бұрын
It seems impl
@KohuGaly
@KohuGaly 2 жыл бұрын
You mention that !Send is sometimes manually (un)implemented for types that rely on thread-locals. Does that mean that auto implementation of Send may cause unsoundness/UB? Or is it "solved" by thread-locals being inherently unsafe to use?
@Yotanido
@Yotanido Жыл бұрын
There shouldn't be any unsoundness in safe code. Manually unimplementing Send or Sync is useful because then your unsafe code can rely on it and actually be safe, whereas with the automatic implementations that unsafe code you wrote would actually be unsafe. Basically, it gives you an additional invariant you can rely on in unsafe code.
@TTrippleT
@TTrippleT 2 жыл бұрын
Audio and video seem to be a little out of sync. I watched it with ~ -250ms for audio in VLC. The live version was fine thou when I watched it briefly, but I might be wrong. Aside from that awesome video as always.
@jonhoo
@jonhoo 2 жыл бұрын
Oh, interesting. I actually found that the video file OBS produced this time around itself was out of sync between audio and video, and fixed that before uploading. Could be that I fixed it too far the other way, or not far enough somehow. Looking at the video again, it looks at least pretty close to me, which is more than I can say about the original video file :p
@TTrippleT
@TTrippleT 2 жыл бұрын
​@@jonhoo Perfectly fine the way it currently is. It is very minor. From the past I know that I'm more irritated by it then normal.
@digama0
@digama0 2 жыл бұрын
impl !Sync for OBS {}
@drip2245
@drip2245 2 жыл бұрын
@@jonhoo Try `use clap;` :)
@user-rq3lx6cy5d
@user-rq3lx6cy5d Жыл бұрын
Thank you, I want know what's your editor font.
@Lexikon00
@Lexikon00 2 жыл бұрын
Isn't your RC implementation UB? Is it fine to dereference a *mut pointer inside a struct through &self? You said it's technically safe because there is no multiple write access to that field and this is correct without Send and Sync but isn't going from & to &mut always UB? Even for struct fields?
@jonhoo
@jonhoo 2 жыл бұрын
Yep, I think I mention that too, and how it'd really need UnsafeCell.
@thepuzzlemaker2159
@thepuzzlemaker2159 2 жыл бұрын
59:01: `static`s also require at least Sync
@alanhoff89
@alanhoff89 2 жыл бұрын
Yeeees!!!!
@kennichdendenn
@kennichdendenn 2 жыл бұрын
23:15 worse yet, two threads concurrently increment, but both increment it to the same value - then, a few drops later and somebody has a pointer - as far as the compiler is concerned - into the depths of hell.
@karelhrkal8753
@karelhrkal8753 Жыл бұрын
I never understood why "duplicating" the Rc is implemented with "Clone". When I clone something, I expect a deep copy, and Rc breaks that. In other words, if I clone it, then mutate the clone, the original is mutated as well! What a mess, honestly.
@FryuniGamer
@FryuniGamer Жыл бұрын
Clone never made any promise regarding "deep" copies. It just guaranteed that you receive a value of the same type behind the reference. The semantic of the trait expects implementations to return a value that is logically the same, but nothing besides that. If you clone the sender side of a channel you now have two senders to the same channel, they are logically the same. Any reference is Clone, since they are also Copy. If you clone one you get two references, two different variables, but pointing to the same thing. If you clone a Vec you are cloning something you own, so you get two things that you own. You can't own the same thing twice, so Vec clones the items. You are mixing the semantics of ownership with the Clone trait. Clone give the same type behind a reference, that type can be anything, owned or not, even another reference. If the thing behind the reference/(smart)pointer is clone you can still clone it directly by doing (*foo).clone()
@karelhrkal8753
@karelhrkal8753 Жыл бұрын
@@FryuniGamer Yes, "clone" doesn't mean "deep clone" in Rust, but it does in other in some other languages. Just another thing to keep in mind, the list just goes on.
@BraxtonMeyer
@BraxtonMeyer 2 жыл бұрын
Hey did my comment get deleted? I asked an interesting question
Crust of Rust: Build Scripts and Foreign-Function Interfaces (FFI)
2:15:42
Crust of Rust: Functions, Closures, and Their Traits
1:06:40
Jon Gjengset
Рет қаралды 84 М.
ТАМАЕВ vs ВЕНГАЛБИ. Самая Быстрая BMW M5 vs CLS 63
1:15:39
Асхаб Тамаев
Рет қаралды 3,9 МЛН
В ДЕТСТВЕ СТРОИШЬ ДОМ ПОД СТОЛОМ
00:17
SIDELNIKOVVV
Рет қаралды 3,9 МЛН
Watermelon Cat?! 🙀 #cat #cute #kitten
00:56
Stocat
Рет қаралды 27 МЛН
Crust of Rust: Atomics and Memory Ordering
2:39:20
Jon Gjengset
Рет қаралды 79 М.
rust macros are magic
14:02
Tantan
Рет қаралды 44 М.
Constructors Are Broken
18:16
Logan Smith
Рет қаралды 100 М.
Tricks of the Trait: Enabling Ergonomic Extractors - Rob Ede
31:52
Rust Nation UK
Рет қаралды 7 М.
I rewrote My Go App in Rust
2:38:22
Tsoding Daily
Рет қаралды 87 М.
Rust at speed - building a fast concurrent database
52:54
Jon Gjengset
Рет қаралды 209 М.
Decrusting the axum crate
2:12:27
Jon Gjengset
Рет қаралды 63 М.
Rust: Generics, Traits, Lifetimes
35:34
The Dev Method
Рет қаралды 44 М.
Crust of Rust: Smart Pointers and Interior Mutability
2:03:04
Jon Gjengset
Рет қаралды 118 М.
Урна с айфонами!
0:30
По ту сторону Гугла
Рет қаралды 6 МЛН
Bluetooth Desert Eagle
0:27
ts blur
Рет қаралды 7 МЛН
Девушка и AirPods Max 😳
0:59
ОТЛИЧНИКИ
Рет қаралды 16 М.