News for hackers. Stuff that matters.
Re:Threads Are a Bad Idea for Most Purposes (1995) [pdf] by brlewis on Tuesday January 28, 2020 @02:03PM (#22172880)
> Java threads work everywhere

That depends how you define "work". Java has a decent concurrency library such that if you have a limited-scope project implemented by 1 or 2 highly-skilled programmers, you stand a good chance of avoiding thread safety issues. But as the project grows, the probability of thread safety issues approaches 1.

> Event driven programming has also become threaded, this is how the whole reactive family of frameworks, node.js, etc, handle parallelism.

Event-driven programming is way less painful than Java threads. With threads, in every place you mutate anything you have to ask yourself, "what happens if my thread is preempted here?" With event-driven programming you only do that sort of thinking in places where you see the `await` keyword.

Re:Threads Are a Bad Idea for Most Purposes (1995) [pdf] by adev_ on Tuesday January 28, 2020 @04:03PM (#22173994)
> Event-driven programming is way less painful than Java threads. With threads, in every place you mutate anything you have to ask yourself, "what happens if my thread is preempted here?"

Event-driven programming is a different pain in the ass but still a pain in the ass.

The current status of the Web speaks for itself: it's event-driven based JavaScript, and it's full of state/transitions bugs everywhere.

In event driven you trade concurrent r/w access issues for a loosing execution contexts issues and out of order issues. The result is often a mess of spaghetti callback close to unreadable.

The less worst of the world might be simply a proper coroutine system, which seems to come to almost every programming language after 30 years of existence

Re:Threads Are a Bad Idea for Most Purposes (1995) [pdf] by oppositelock on Tuesday January 28, 2020 @02:56PM (#22173428)
You can write horrible event driven code. For example, do your events need to talk to a database? Right there, you've got a synchronization point.

Thinking about asynchronous behavior is always tricky, and code designed to run on threaded systems isn't generally arbitrary code with locks thrown into it the mix, you strive to write the largest possible reentrant sections, and only lock where you have to, and as infrequently as possible. With reentrant code, it doesn't matter where you get preempted.

Re:Threads Are a Bad Idea for Most Purposes (1995) [pdf] by lmm on Tuesday January 28, 2020 @09:26PM (#22176606)
> For example, do your events need to talk to a database? Right there, you've got a synchronization point.

Not if you do it right. Interacting with sync-only systems from async systems is a problem, but it's not fair to blame that on async - if you make the whole system work async, you don't have that problem.

Re:Threads Are a Bad Idea for Most Purposes (1995) [pdf] by Bjartr on Tuesday January 28, 2020 @04:50PM (#22174428)
> That depends how you define "work".

I don't disagree with what you've said, I just wanted to chime in that in the context of the conversation to this point the definition is something in the ballpark of "are available cross-platform without jumping through hoops".

Re:Threads Are a Bad Idea for Most Purposes (1995) [pdf] by brlewis on Tuesday January 28, 2020 @04:55PM (#22174500)
I was replying in the context of "This paper came at a time when threads were really painful to work with," which seemed to imply that they're no longer really painful to work with.
Re:Threads Are a Bad Idea for Most Purposes (1995) [pdf] by pierrebai on Tuesday January 28, 2020 @02:52PM (#22173390)
That may be true in some language, but it is not generally true. The awaited task can run in parallel and both are only re-sync when you use the result. Thus anything can also be mutated in parallel with await/async style of programming.
Re:Threads Are a Bad Idea for Most Purposes (1995) [pdf] by trhway on Tuesday January 28, 2020 @02:12PM (#22172983)
>Event-driven programming is way less painful than Java threads. With threads, in every place you mutate anything you have to ask yourself, "what happens if my thread is preempted here?"

in 23 years programming Java (and in the all places where i've worked having been recognized as local expert on threads and synchronization, incl. in the current very large C++ platform project) i have never asked myself that question in the context of the mutation of data.

Re:Threads Are a Bad Idea for Most Purposes (1995) [pdf] by plapetomain on Tuesday January 28, 2020 @02:34PM (#22173204)
Well you either did ask that question and answered it by using appropriate locking and concurrent data structures (which is basically implicitly asking and addressing that question..) or you wrote a lot of crash prone shitty software. Which one was it?
Re:Threads Are a Bad Idea for Most Purposes (1995) [pdf] by trhway on Tuesday January 28, 2020 @02:47PM (#22173338)
Locking isn't about preemption. You can have a system without preemption and still have to use the locks and other concurrent primitives.
Re:Threads Are a Bad Idea for Most Purposes (1995) [pdf] by lowbloodsugar on Tuesday January 28, 2020 @03:15PM (#22173596)
Not sure why the downvotes. If a system has enough CPUs, threads might never be preempted, and yet we must still use locks or concurrent primitives if we are sharing resources across multiple threads.

I don't think I've actually thought about preemption explicitly since the Nintendo64 days when thread priorities figured into our locking strategy. But then we'd also re-implemented the scheduler and, at times, turned off the official OS to go do something we needed to do without interruption. So, like I said, preemption not high on my radar these days, as it falls under the general category of "concurrency". Even an iPhone has 4 CPUs.

Re:Threads Are a Bad Idea for Most Purposes (1995) [pdf] by samatman on Tuesday January 28, 2020 @06:59PM (#22175583)
The question shouldn't have been about preëmption, but rather, "what if some other thread mutates my data here?"

The effect is much the same, whether the race is caused by task scheduling, or just because another core got there first.

Re:Threads Are a Bad Idea for Most Purposes (1995) [pdf] by gpderetta on Tuesday January 28, 2020 @09:07PM (#22176481)
Or even if some random function you called fired some callback that just mutated some state you were in the middle of changing.
Re:Threads Are a Bad Idea for Most Purposes (1995) [pdf] by StillBored on Tuesday January 28, 2020 @07:03PM (#22175615)
Locking and preemption are different but sometimes related concepts. As you mention.

Modern kernel people still have to worry about locking as well as preemption, if you look at the NT native API's you will see dispatch levels, which control whether kernel threads can be prempted for higher priority activities, linux is similar with the _irqsave() and preempt_ calls.

Is this for example important when syncing with an interrupt handler (no preempt/rt config), which is why there are both spin_lock() and spin_lock_irqsave() which implicitly blocks irq preemption. AKA if you grab a lock that is needed by say an interrupt handler, then you take said interrupt the machine will deadlock because the scheduler won't deschedule the interrupt handler.

Re:Threads Are a Bad Idea for Most Purposes (1995) [pdf] by kstenerud on Tuesday January 28, 2020 @03:09PM (#22173548)
What purpose would locks and concurrent primitives have in a system where running code is not preempted?
Re:Threads Are a Bad Idea for Most Purposes (1995) [pdf] by trhway on Tuesday January 28, 2020 @03:35PM (#22173772)
In addition to parallel in all senses/levels systems mentioned by the other commenter, another example would be a truely single threaded hardware with cooperative or even sequential multithreading where you'd use locking/etc. to safeguard your memory model invariants against for example compiler, JIT and hardware optimization shenanigans.
Re:Threads Are a Bad Idea for Most Purposes (1995) [pdf] by StillBored on Tuesday January 28, 2020 @07:05PM (#22175640)
To guarantee two different threads don't try to simultaneously mutate (or in some cases access) shared resources.
Re:Threads Are a Bad Idea for Most Purposes (1995) [pdf] by pmarreck on Tuesday January 28, 2020 @02:28PM (#22173153)
> But as the project grows, the probability of thread safety issues approaches 1.

This is exactly why I run unit tests concurrently (other than the speed boost), and try to write the tests (and the code) so that it won't break when run concurrently (like inserting something into a DB and then assuming success only if the count has gone up by exactly 1).

Re:Threads Are a Bad Idea for Most Purposes (1995) [pdf] by brlewis on Tuesday January 28, 2020 @02:37PM (#22173232)
Are you saying that concurrency issues can reliably be found via testing?
Re:Threads Are a Bad Idea for Most Purposes (1995) [pdf] by pmarreck on Tuesday January 28, 2020 @04:05PM (#22174011)
Well, they can't be deterministically found since process scheduling is not deterministic (notable exception: Haskell, I believe, has a way to do deterministic concurrent scheduling!), but I have definitely seen fails that only crop up when the suite is run concurrently, and it usually turns out that the code failing in those circumstances has made assumptions about application state that do not hold true in a concurrent context
Re:Threads Are a Bad Idea for Most Purposes (1995) [pdf] by btilly on Tuesday January 28, 2020 @04:38PM (#22174327)
OK, intermittently your test suite fails nondeterministically 0.01% of the time. Do you imagine that this will be sufficient to find which of the last thousand commits introduced the bug?

I would recommend using specialized tools for the task like Intel's Thread Inspector or Coverity's Helgrind.

Re:Threads Are a Bad Idea for Most Purposes (1995) [pdf] by pmarreck on Tuesday January 28, 2020 @04:53PM (#22174467)
Or one could simply try very hard not to mutate any state that is available to another process and corral all such code that requires doing so (which most of the time ends up being only a small portion of the code; the rest can be designed functionally, just passing values in and back out with no other side-effects) into a thin I/O layer, which is (I believe) the Hexagonal Architecture and is explained quite well by Gary Bernhardt here: https://www.destroyallsoftware.com/talks/boundaries
Re:Threads Are a Bad Idea for Most Purposes (1995) [pdf] by btilly on Tuesday January 28, 2020 @05:15PM (#22174698)
This is not an either or, it is an and.

The one being a good idea doesn't preclude the other from being a good idea as well. Do them both.

(And also avoid concurrency wherever you can. And of the available forms of concurrency, threads are one of the worse ones.)

Re:Threads Are a Bad Idea for Most Purposes (1995) [pdf] by pmarreck on Tuesday January 28, 2020 @06:28PM (#22175340)
Agree!