Crossbeam Vs Standard Threads

Hi everyone,

I've been exploring concurrency in Rust and came across the Crossbeam crate. I understand that it's often recommended over standard threads (std::thread) for certain use cases, but I'm curious about the technical details behind why Crossbeam is considered better in many ways.

Could someone explain:

  1. How Crossbeam Works:
  • How does Crossbeam manage threads differently compared to standard threads?
  • How does it handle memory management and ensure safety without the need for Arc<Mutex<T>?
  1. Advantages Over Standard Threads:
  • How does Crossbeam achieve lock-free concurrency?
  • In what scenarios does Crossbeam provide higher performance?
  1. When to Use Which:
  • When should I stick with standard threads?
  • When does it make more sense to use Crossbeam?

Looking for a detailed, easy-to-understand explanation that covers the under-the-hood implementation and real-world use cases.

Thanks in advance!

1 Like

Crossbeam offers scoped threads. That's mostly for problems where you want to put a lot of CPUs to work on the same problem by dividing it into subproblems. Each subproblem must finish before its parent thread can finish. They're still OS threads.

If you have a problem that fits that model, it's useful. If you don't, it's not. Note that this is totally different than "async", which is useful when most of your tasks are waiting for network input and nothing is compute-bound.

Crossbeam's channels are generally useful. There are lots of Rust crates for channels and queues. Some handle panics well, and some don't. Some are fair, and some aren't. Some are lockless, and some aren't.

What are you trying to do?

1 Like

I'm not sure you understand what crossbeam is. It provides some utilities for assisting in concurrent programming, it is not itself a multithreading solution. It provides utilities for working with threads (and, yes, scope, but that's also in std: "Note: Since Rust 1.63, this function is soft-deprecated in favor of the more efficient std::thread::scope.").

By using the same basic ideas (locks and shared heap allocations) to build other primitives like channels. You're not getting a different kind of synchronization primitive, just a different implementation. If you're worried about the performance of crossbeam channels vs. std channels, don't be: std uses crossbeam's implementation, just with a slightly different exposed interface.

It doesn't, not entirely. Where it does though, it uses atomics (where the CPU itself guarantees a certain order of operations on a given memory address; but they only work on small regions of memory, e.g. 8 bytes). You can use atomics from std::sync::atomic if you want.

Higher performance than what? Than handmade abstractions? Whenever they did it better than you did, which is probably always. But only if you know why you want to use their tools, and when to use them, and how.

Whenever you don't want whatever abstractions crossbeam is offering. They're still using threads, just with some fanciness on top. It comes down to what you need in any given scenario, which is too specific to give useful general advice - especially since crossbeam offers a number of different utilities, which must be addressed separately, since they're separate things.

2 Likes