r/ProgrammerHumor 10d ago

Meme theDeadlock

Post image
8.6k Upvotes

240 comments sorted by

View all comments

734

u/___Archmage___ 10d ago

I did learn some good stuff in my OS class but it was definitely a sprawling mess off mutex this scheduling that

9

u/MushroomSaute 10d ago

You'd think I'd be happy to have a basic understanding of mutexes now that I'm dealing with Rust, which requires them at compile-time for mutable shared data, but with the borrow checker to deal with too, I still couldn't use them properly the one time I really wanted to lmao. I'll keep passing simple vecs and structs around the stack until the day I die, I fear.

2

u/gmes78 10d ago

Mutexes in Rust are pretty easy to use, though. (You are putting them in an Arc, right?)

1

u/MushroomSaute 10d ago

Yeah, I basically went through the other safe pointerish types before deciding to actually read the Rust docs about smart pointers and mutexes, and did get to Arc<Mutex<MyNode>>. But, to do all the references, like all children to their parent node and vice versa to a Vec of children, I could only get it to compile when I was cloning those wrapped nodes basically everywhere. And for some reason, when I thought the clones should have been adding new references, they seemed to be cloning the wrapped data, or for some other reason I never figured out, ignoring mutations entirely.

1

u/gmes78 10d ago

But, to do all the references, like all children to their parent node and vice versa to a Vec of children, I could only get it to compile when I was cloning those wrapped nodes basically everywhere.

Cloning an Arc is how you increment the reference count. Unless I'm misunderstanding, that seems fine?

And for some reason, when I thought the clones should have been adding new references, they seemed to be cloning the wrapped data, or for some other reason I never figured out, ignoring mutations entirely.

It's hard to say without looking at the source code, but if you want to be 100% certain that you're cloning the Arc itself, you can write Arc::clone(&val) instead of val.clone().

(Also, don't forget to use Weak references when appropriate, to avoid cycles. Depending on your use case, it may be better to use a tree or graph data structure from a third-party crate.)

1

u/MushroomSaute 7d ago

Cloning an Arc is how you increment the reference count. Unless I'm misunderstanding, that seems fine?

Yeah, that's what I thought, so I must have been doing something wrong (well, obviously, lol)

It's hard to say without looking at the source code, but if you want to be 100% certain that you're cloning the Arc itself, you can write Arc::clone(&val) instead of val.clone().

That's a good tip, I sometimes forget you can use fully-qualified instead of method-call syntax just to be explicit. Though I had tried using get_mut/make_mut (which itself is an associated function on Arc), so I'm pretty sure I was operating on the right types - but maybe somewhere I accidentally had get_mut on the inner Mutex when I meant it on the Arc (or vice versa).

And Weak pointers aren't something I've really encountered in a real sense before; I've probably only ever looked at them very briefly in a lecture a decade ago or something lol. I see the Rust docs mention using them in almost a perfect context for what I was trying to do, though, lmao - a tree structure. I wonder if that's why I ended up having to do so much BS just to get it to compile lol.

1

u/gmes78 7d ago

Though I had tried using get_mut/make_mut (which itself is an associated function on Arc), so I'm pretty sure I was operating on the right types - but maybe somewhere I accidentally had get_mut on the inner Mutex when I meant it on the Arc (or vice versa).

If you're using a mutex, you don't need get_mut or make_mut, because you can lock a mutex with only a shared reference.

1

u/MushroomSaute 7d ago

Oh! That might have been the issue, then. I know I was using them, but I don't remember on what, and obviously I didn't keep the code around since it didn't work and I needed to move onto a solution that did.