简体   繁体   中英

Can I ignore thread safety when programming in Erlang?

I've just started learning about thread safety. This is making me code a lot more defensively, perhaps too defensively.

Would using a functional language like Erlang completely rid me of this concern?

in Erlang the unit of execution state isn't a thread, but a process. yeah, it's a lightweight kind of process implemented on top of threads; but it's more like a process than a thread.

The main point is that processes don't share state, they pass messages; while threads share everything by default, and have to arbitrate to avoid chaos.

thus, you don't need thread safety since you're not working with threads.

Javier is right.

However, I'd like to just add something as it has caught me before. If you are working with a built-in driver or nif it may not be thread safe anymore. It seems obvious since the driver or nif will be using C or C++ code, but it's worth mentioning. So you can't completely ignore thread safety just because you are using Erlang.

No. See Erlang Style Actors Are All About Locking . It is much easier to achieve thread safety in a functional language, but you do need to think about it.

I've just started learning about thread safety. This is making me code a lot more defensively, perhaps too defensively.

Note that in that case it's very likely you are still getting things wrong. Shared-everything concurrency is very very hard to get right in anything except most trivial examples.

No, you still need to consider thread safety in Erlang, but the problems are much simpler to solve.

I read an article in which the author pointed out that your message API can cause threading issues. The example revolved around a bank account. His initial message API had GET and SET operations. Some code that wanted to deposit $100 would GET the current value, add 100 to it, and then SET the result. Of course, this only works if a single process is accessing the bank account. Once two processes are manipulating the balance, all bets are off.

His solution was to change the message API to DEPOSIT and WITHDRAW (he actually uses one message - UPDATE - but you get the idea). This causes the interaction to assume atomic semantics - the listening process will only process one deposit or withdrawal at a time, and will block other requests until the first is complete.

It's worth noting that this problem is essentially the same as the shared-memory problem. (If we use GET and SET messages to interact with a process, we have essentially created some shared memory). Another blogger compares ets to shared memory as well. However, as long as you understand where you have introduced shared-memory-like constructs and regulate access to that shared memory, you shouldn't have any threading issues (other than deadlock, of course).

Disclaimer: I know virtually no Erlang. Take my opinion with a grain of salt.

A purely functional language that (obviously) only allows "pure" functions. Wiki says pure functions are always thread-safe, thus confirming my gut feeling on that topic.

But I don't know if Erlang is purely functional (wiki implies otherwise, so I guess it isn't). Perhaps it uses other means of achieving thread-safety. Anyway, its data structures are (mostly? exclusively?) immutable, and are thus inherently thread-safe. And being a functional language, at least idiomatic Erlang code won't use (muc? any?) global variables but use pure functions instead. Those are thread-safe. But things I/O may still be an issue... if an Erlang program reads and writes a file concurrently, such code unlikely not thread-safe. But most of the time, you'll be fine thanks to immutable data structures and such.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM