Live data from Hacker News

Ruby core classes aren't thread safe

jstorimer.com

31–40 of 47 posts

Re: Ruby core classes aren't thread safe

#31
post #20

Earlier quoted context omitted.

> Under the semantics described here, Java or C# core classes aren't "thread-safe" either and I'd expect the vast majority of standard libraries to completely fail the test (potential winners: Clojure using an immutable collection bound on an atom, as they have compare-and-swap semantics; and probably Haskell somehow) Java's standard library includes Doug Lea's famous java.util.concurrent package written as part of J…

> Java's standard library includes Doug Lea's famous java.util.concurrent package written as part of JSR 166 Irrelevant, java.util.concurrent.atomic.AtomicIntegerArray - which I mentioned — can not under any sensible definition be called a "core collection".

And it highlights the issue that thread safe collections and thread safe objects are very different things. ConcurrentHashMap may be thread safe but putting non atomic Integers in there still leaves you vulnerable to threading problems

Re: Ruby core classes aren't thread safe

#32

Earlier quoted context omitted.

> Java's standard library includes Doug Lea's famous java.util.concurrent package written as part of JSR 166 Irrelevant, java.util.concurrent.atomic.AtomicIntegerArray - which I mentioned — can not under any sensible definition be called a "core collection".

And it highlights the issue that thread safe collections and thread safe objects are very different things. ConcurrentHashMap may be thread safe but putting non atomic Integers in there still leaves you vulnerable to threading problems

> ConcurrentHashMap may be thread safe but putting non atomic Integers in there still leaves you vulnerable to threading problems

Yes, thread-safety is hard in these languages. You have to think about code when you write it.

Re: Ruby core classes aren't thread safe

#33
post #26
post #18

It's not that Arrays are not thread safe; it's just that the code was written in a non-thread-safe way. Writing x[i] -= 1 actually means x[i] = x[i] - 1 So, there's a read, a subtraction, and a write, and they all happen sequentially. Since they are not in a transaction or protected by a mutex, nothing guarantees that other thread don't mutate `x[i]` in the mean time. This has nothing to do with Ruby, and nothing to…

That's not quite true. The language spec can mandate that the -= be atomic (the X86 equivalent is mandating a LOCK).

Technically it'd have to mandate that []-= be atomic, there's a load from and a store to a k:v collection, not just from and to memory.

Re: Ruby core classes aren't thread safe

#34
post #30

Earlier quoted context omitted.

> Java's standard library includes Doug Lea's famous java.util.concurrent package written as part of JSR 166 Irrelevant, java.util.concurrent.atomic.AtomicIntegerArray - which I mentioned — can not under any sensible definition be called a "core collection".

The "core collections" - a term you're defining yourself right now however you like, for the record - aren't threadsafe for a reason. They have different performance characteristics in Java! You need two versions of the collections in these languages because of their concurrency and memory models. In Java, using Concurrent/Atomic classes is how you write idiomatic threadsafe code, and it has been for a decade. Bitchi…

Wow, you went way off kilter there mate, I didn't "bitch because the main list types aren't threadsafe", in fact I didn't even emit the slightest criticism (let alone "bitch") on that front as it makes perfect sense, you're the guy getting all butthurt because I note in passing that Java's or C#'s core collections are no safer than Ruby's if you're using them in a stupid manner.

Chill and lay off the exclamation point.

Re: Ruby core classes aren't thread safe

#35
Hi. OP here.

Thanks for the comments about atomicity vs. thread-safety. Absolutely on point. The article started out demonstrating what happened with concurrent Array mutation, but then I put in that += operation and didn't address it. Sorry for not making the distinction. Atomicity is absolutely a different issue than a thread-safe collection. I'm publishing something new tomorrow that addresses this point.

To bring things back to code, the point I was originally trying to make is that this code is not thread-safe.

  array = []
  threads = []

  10.times do
    threads 
Specifically, too many Ruby programmers won't think twice about this operation not being thread-safe:

  array.push(item)
But there's no such guarantee. This is demonstrated nicely when this code example is run on an implementation with no global lock, try it on JRuby.

Re: Ruby core classes aren't thread safe

#38
post #26
post #18

It's not that Arrays are not thread safe; it's just that the code was written in a non-thread-safe way. Writing x[i] -= 1 actually means x[i] = x[i] - 1 So, there's a read, a subtraction, and a write, and they all happen sequentially. Since they are not in a transaction or protected by a mutex, nothing guarantees that other thread don't mutate `x[i]` in the mean time. This has nothing to do with Ruby, and nothing to…

That's not quite true. The language spec can mandate that the -= be atomic (the X86 equivalent is mandating a LOCK).

Totally agreed. Why do I have to lock it myself (even on a high level language like Ruby)? I'm not programming for C!

Re: Ruby core classes aren't thread safe

#39
post #12

Earlier quoted context omitted.

> and probably Haskell somehow By design - pure values are always thread safe.

Pure values are not really relevant: you still need to update a binding somewhere to synchronize, and that's sufficient for your race. The clojure example wouldn't be safe if atoms weren't compare-and-set: have collection state A, thread one applies A->B, thread two applies A->C, the two threads set the atom (atomically but not CAS) and an increment has been lost even though all values are pure.

Mutating collections with shared state isn't what you do in pure Haskell, though. That's the difference between the now classic deterministic parallelism , and the newer side-effect oriented concurrency in Haskell using stm or mvars.

Without side effects your /parallel/ code cannot but be thread safe. Because the language requires the implementation to ensure side effects under the hood are not observable -- using cas for example on thunk updates, as GHC does.

Post reply on HN