Hacker Read top | best | new | newcomments | leaders | about | bookmarklet login

It would've been nice if the author had described the change that they made instead of just writing "consider the following code".

They do say "you generally want to use something that synchronizes that state", but then fail to describe exactly which method they selected in this particular example. A single sentence explaining the particular change would've been sufficient.

This is a little thing but would greatly improve the communicability of the post and practices greater empathy for the reader.



sort by: page size:

> You've moved your argument from "synchronization always must have a source and destination" to "certain synchronization models are not well suited to some use cases".

No, I have moved from specific examples to general examples, and general rules. The most general rule is that synchronization cannot be automatic and have a desirable outcome.


> I'm having trouble thinking of a real world example where you'd want an atomic operation going ham in a loop without any sort of time or synchronization.

By using another atomic op as synchronization? After all that's their stated purpose.


> To serialize access, protect the data with channel operations or other synchronization primitives such as those in the sync and sync/atomic packages.

> If you must read the rest of this document to understand the behavior of your program, you are being too clever. Don't be clever.

I'm surprised that they list sync/atomic as a thing to use. As I recall its behaviour isn't even defined--I followed a long mailing list thread trying to find out that ended with 'these are the behaviours we know we want but it's too complicated to document so let's just keep this to ourselves'.


> The rest is in the code.

I know that philosophy well, but I do not really agree with it - not at all. For example in concurrent code written in C, the way things are synchronized is normally implicit. You can understand it if you read all of the code, but not by looking at single functions. If you add accesses without proper synchronization, you will get quickly undefined behaviour which can cause extremely nasty concurrency bugs.

I also agree with the several comments made that it is often more helpful "why" something is done, than "how". This is, of course, valid for in-code comments as well, but IMO equally important in overview documentation.

> And 80% of all »projects« lack at least one of the points above.

Yeah, I know. In fact, I have rarely seen good technical documentation.


> You wouldn't think that writing synchronization software would be rocket science, but apparently it is

It really is, depending on your constraints. It's one of those charming problems that starts at "Why don't you just ___?" and quickly devolves to "Okay, so we can probably avoid creating an inconsistent state here so long as edgecase0, edgecase1, and edgecase38 don't occur at the same time."


> I guess you can have a distributed locking mechanism, either scope or line-driven

In real time? How would that solve the problems outlined in the article?

> However, this workflow probably detracts greatly from the real time intent

Seems like you understand the problem.


Tiny comment: I think the sentence "However, in practice the overhead needed to correctly avoid locks is greater than just using a mutex." should be part of footnote 1, not the main text.

> mind expanding on this part?

Certainly. That part is a sentence written to be short and catchy. It sacrifices precision for reasons of brevity and style. It also doesnt mention either concurrency or parallelism, it just uses the word "parallel".

This is acceptable, because the post goes on to more precise statements later on, quote:

    It works for both i/o bound concurrency and cpu bound parallel computing.
End Quote.

>The other examples are also lacking a lot of details. 30 seconds of latency can be bad, of course. But so can adding concurrency to a team that doesn't understand it well.

It might also be that it's not worth spending effort on speeding up some script like this. How often does it run?

Do these 30 seconds matter? Maybe they do now but they didn't in the beginning, but then that's ok, too, and you refactor.


> This reads like a system design interview, and a good one.

> The author clearly understands the pattern and the technologies they’re working with.

We must have read a different article.

The one I read put a big lock around the outside of their interface and called that "concurrent". This is not what is normally meant by the term.

This was after a dozen or so pages that described an insertion sort poorly, and followed by some speculation about why their software still didn't work right.


> Does anybody know what they were thinking?

Ergonomics. (Plus an inherent assumption of mutable data.)

You can write `synchronized (this)` or `synchronized` class method, etc. and it just works.


> I wonder if things like volatile and lock-free algorithms would behave any differently or even break.

I don't understand how do you think it could change or break a volatile or lock-free algorithm?

It's a transparent optimisation - it doesn't change observable behaviour. Just like how register renaming, top-of-stack-caching, and so on and so on don't change observable behaviour.

The only difference it would make is timing.


> I highly recommend reading the "What is structured concurrency?" section with understanding. I think this is a big deal.

The idea was originally introduced and explained in more depth here: https://250bpm.com/blog:71/


> They said something that I thought was clear: you need file locks with read() and write().

You need _synchronization_. Not necessarily one of mmap() or file locks.


> There is no source nor destination, it's a merge of two equivalent trees.

Let's say I have two systems in a programming project. On one of the systems, I have edited some files, but now realize I have created a bug I can't locate and I don't want to try to undo what I have done -- I just want system B to be returned to its original state, a state represented by system A, but with a minimum of file operations.

So I run a synchronization operation, and I tell the algorithm how to proceed. If I follow your philosophy --

"You're still thinking in files. There are no files, just actions. The files are a byproduct, not the things being synced."

-- then (using the default rules of two-way file synchronization), the edited files, the files I have ruined, files having newer dates than the originals, will be copied onto the original source tree, tree A, and I will lose the only remaining copies of the files' original states. If instead I delete the edited copies to avoid this, the originals will be deleted too.

So much for automatic file synchronization without the operator understanding and overseeing the process.

Your reply doesn't analyze file synchronization operations with enough depth to avoid such disasters.


> Especially when the author gave a very clear use case for a very real problem in shared state computing.

He did not. One server can just keep track of a player's items then pass that state on when he moves to the next adjacent server. I don't even see the issue here except the codebase is described as something very messy with weird OO/hooking style non-abstractions that just cause bugs.


> Just over five years ago, in November of 2018, when Structured Concurrency was a little-known peculiarity,

First time hearing about it. Wish the post would at least link to what it is.


> Practically all server applications require some sort of synchronization between multiple threads.

It could be just me but I think the author should've mentioned alternative concurrent programming models available for JVM such as Akka.


>synchronization points are explicit

Hmmm, I'd have just called it cooperative threading/multitasking then. Or do you think that would be wrong?

next

Legal | privacy