3 ms·
Just because code is written in an asynchronous style doesn't prevent correctness errors that would not exist with locking. For instance, using everyone's favor
by vore 7y ago
Just because code is written in an asynchronous style doesn't prevent correctness errors that would not exist with locking. For instance, using everyone's favorite example, a bank:
In no particular order:
1. Pizza company debits by balance by $5
2. I withdraw $5
Assuming both those operations can yield due to e.g. async requests and that they can be resumed at any point, I don't know which order they will yield or resume in.
Consider this interleaving:
1.1. Get balance, I have $5
2.1. Get balance, I have $5
1.2. Set balance to $0
2.2. Set balance to $0 (but there are total debits of $10!)
With locking:
1.0. Acquire account lock
1.1. Get balance, I have $5
2.1. Get balance: wait on lock
1.2. Set balance to $0
1.3. Release account lock
2.1. Get balance, I have $0
2.2. Can't set balance, will overdraw!
With regards to resource contention, anything that causes a waiter graph cycle can cause deadlocking, regardless of single- or multi-threading. I can't think of a compelling example here, but nobody expects to have deadlocks yet they still happen :)
- DecoPerson 7y agoAn example of a deadlock that continues the bank balance analogy: A transfer funds method that does: 1. Lock account A 2. Get balance and check 3. Lock account B 4. Debit account A 5. Credit account B If the two accounts transfer to each other at the same time, you can get: 1. A->B: Lock account A 2. A->B: Get balance and check 3. B->A: Lock account B 4. B->A: Get balance and check 5. A->B: Lock account B -- deadlock One solution is to always acquire locks in the same order and release all of them when you fail to obtain one. You can do this in the transfer example by sorting by account ID (so always lock A before B).
- Arelius 7y agoSure enough, but in javascript if your balance operations can yield due to async requests than you already have a bigger problem than a shared in-memory variable. Which is really the only case a standard os-lock can solve. Let's say that balance is in a database or behind a REST api. An os-lock won't solve the problems of other processes trying to update that same resource.
- vore 7y agoYou can imagine a function being unintentionally promoted into async-world for some kind of cross-cutting concern even if the data is stored in memory, e.g. if logging requires an async call, or if reporting metrics requires an async call. While I agree that in the general practice in JavaScript programming stops you from this kind of footgun, you can still be caught off-guard if you end up thinking that this programming style is immune to this kind of problem: locking is a big hammer with its own problems, but it will never cause data incorrectness.
- jnbiche 7y ago> Just because code is written in an asynchronous style doesn't prevent correctness errors that would not exist with locking. Yes, that's why I referenced passing around a reference to an immutable data structure, which is fairly common in JS.
- vore 7y agoHow will you update the bank account with an immutable data structure? You need to mutate the balance somewhere.
- jnbiche 7y agoWell, in practice you're presumably using a database, which has transactions in the API you're using. But to answer your question, in functional programming (also frequently ReactJS, if you use libraries like Redux), you don't mutate the data structure. You create a new data structure based off the old one. Am I misunderstanding your question? Just because you use an immutable data structure doesn't mean it can't be updated.
- dboreham 7y agoDatabase written in not(Javascript) of course, since it has to work and handle concurrency properly.
- jnbiche 7y agoYes, of course. Why would you build a database in JS? And does gmail not work well for you? Most of us are only using JavaScript because that's the only way to build browser applications (or compile-to-JS languages, which still require an understanding of JS or you'll run into problems). In any case, I don't particularly like JS, so your dig fell short. But JS is necessary for many of us.
- zo1 7y ago> "Most of us are only using JavaScript because that's the only way to build browser applications (or compile-to-JS languages, which still require an understanding of JS or you'll run into problems)." The javascript apocalypse is inevitable, we're just yet to reach the tipping point where this hard-requirement to use JS for web/browser applications is no longer there.
- jnbiche 7y ago> With regards to resource contention, anything that causes a waiter graph cycle can cause deadlocking Maybe I'll learn something here, but can you explain how an async runtime with no locking primitives like JS could cause a waiter graph cycle?
- random314 7y agoYou don't need locking primitives for a deadlock. Await is sufficient.