If you have a single atomic instruction, the execution of that instruction alone will be atomic and you don't need a lock for it per se. However, the input arguments for that instruction may change, or you may have other threads writing to the same output of that instruction.
In general, individual instructions will be atomic (in the sense that a processor will execute the instruction in 1 clock cycle). The issue is that instructions don't operate in isolation and their inputs / outputs may be modified by other threads. Also, recall that instructions need to read/write data for it to be affected by other threads -- so if you're doing something like add
, you presumably read data for that add
at some point in the past. This is now at least 2 operations (load
and add
), and those 2 operations together are not atomic (and you may need a lock to make them thread-safe).
I am very interested in knowing which programming languages include an atomic
-like keyword. It seems like a desirable for any language. Is it only very parallel computing-specific languages?
If we use an atomic on an int in C++, does that mean we don't need to lock around increments or decrements on that int? Since the thread's increment on that x (which presumably includes a load, add, and a store asm instruction) would all be guaranteed to happen at once without interference from other threads?
If we use an atomic on an int in C++, does that mean we don't need to lock around increments or decrements on that int.
It depends on the memory order and application logic (around how different threads read / write the atomic int). https://stackoverflow.com/questions/31978324/what-exactly-is-stdatomic and https://en.cppreference.com/w/cpp/atomic/memory_order are two good pointers to read more.
In terms of other languages, perhaps this isn't the exact answer you were looking for, but the first time I saw atomic-like functions was embedded systems. We used binary semaphores (which is basically a lock) to grant access to stuff like printing or shared variables among RTOS tasks. Otherwise, with multiple tasks (aka. threads) trying to print, you would get a jumble of words. It was later that I learned the general use of this!
That's super interesting that some languages provide support for code block atomicity - I wonder what's the advantage of having that instead of just having a lock/unlock mutex around a critical section... probably just readability and consistency reasons maybe.
Please log in to leave a comment.
Is there a case where you need a lock even for a single atomic instruction? For example, can you run into issues if multiple threads run that same instruction in the same clock?