In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-01-21 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/02 Report--
This article introduces the relevant knowledge of "what is the difference between atomic operation and mutex in Go language". In the operation of actual cases, many people will encounter such a dilemma, so let the editor lead you to learn how to deal with these situations. I hope you can read it carefully and be able to achieve something!
The atomic operation is an uninterruptible operation, the intermediate state of the atomic operation cannot be seen from the outside world, either the atomic operation has been completed or the atomic operation has been completed. In the process of performing atomic operations on a value, CPU will never perform other operations on that value, so other operations are also atomic operations.
The atomic operations provided in the Go language are non-intrusive, and the relevant atomic functions are provided in the standard library code package sync/atomic.
Increase or decrease
The name of the function used to add or subtract an atomic operation begins with "Add", followed by a specific type name. For example, the following example is an atomic subtraction of type int64.
Func main () {var counter int64 = 23 atomic.AddInt64 (& counter,-3) fmt.Println (counter)}-output---20
The first parameter of the atomic function is a pointer to the variable type, because the atomic operation needs to know where the variable is stored in memory, and then give a special CPU instruction, that is to say, it is impossible to perform atomic operations on variables that cannot get the memory storage address. The type of the second parameter is automatically converted to the same type as the first parameter. In addition, the atomic operation automatically assigns the value after the operation to the variable, so there is no need for us to assign the value manually.
For atomic.AddUint32 () and atomic.AddUint64 (), whose second arguments are uint32 and uint64, it is not possible to pass a negative value directly for subtraction. Go provides another way to do this in a roundabout way: using the feature of binary complements.
Note: values of type unsafe.Pointer cannot be added or subtracted.
Compare and exchange (Compare And Swap)
Referred to as CAS, several functions prefixed with "Compare And Swap" in the standard library code package sync/atomic are CAS operation functions, such as the following
Func CompareAndSwapInt32 (addr int32, old, new int32) (swapped bool)
The value of the first parameter is the pointer to the variable, the second parameter is the old value of the variable, and the third parameter refers to the new value of the variable.
Running process: after calling CompareAndSwapInt32, it will first determine whether the value on this pointer is equal to the old value, if so, overwrite the value with the new value, if equal, then the later operation will be ignored. Returns a swapped Boolean value indicating whether a value replacement operation has taken place.
It is different from locks: locks always assume that concurrent operations will modify the value being operated, while CAS always assumes that the value has not been modified, so CAS has a lower performance loss than locks, locks are called pessimistic locks, and CAS is called optimistic locks.
Example of using CAS
Var value int32func AddValue (delta int32) {for {value if atomic.CompareAndSwapInt32 (& value,v, (v+delta)) {break}
As you can see from the example, we need to use the for loop multiple times to determine whether the value has been changed. To ensure the success of the CAS operation, exit the loop only if the CompareAndSwapInt32 returns true, which is similar to the spin behavior of the spin lock.
Loading and storage
When a value is read or written, it does not mean that the value is up-to-date, or it is possible that the original value is changed as a result of concurrent writes in the process of reading or writing. To solve this problem, the standard library code package sync/atomic of the Go language provides an atomic read (Load prefix function) or write (Store prefix function) a value
Change the above example to atomic reading
Var value int32func AddValue (delta int32) {for {atomic.LoadInt32 (& value) if atomic.CompareAndSwapInt32 (& value,v, (v+delta)) {break}
Atomic writing always succeeds because it does not need to care about the original value, but the old value must be concerned in CAS, so atomic writing cannot replace CAS. Atomic writing contains two parameters, such as the following StroeInt32:
/ / the first parameter is the pointer to the operated value, and the second is exchanged by the new value func StoreInt32 (addr * int32, val int32) of the operated value.
Functions that start with "Swap" are called "atomic swap operations" and are similar to the previously mentioned CAS operations and atomic write operations.
Func SwapInt32 (addr * int32, new int32) (old int32)
Take SwapInt32 as an example, the first parameter is a pointer of type int32, and the second is the new value. The atomic exchange operation does not care about the original value, but sets the new value directly, but returns the old value of the manipulated value.
Atomic value
The standard library code package sync/atomic of the Go language contains an atomic value called Value, which is a structure type that stores values that need to be read and written by atoms. The structure is as follows
/ / Value provides atomic loading and stores values of the same type. The zero value of / / Value returns nil from Load. / / after calling Store, the value must not be copied. / / values may not be copied after first use. Type Value struct {v interface {}}
You can see that there is a v interface {} inside the structure, which means that the Value atomic value can hold any type of value that needs to be read and written by the atom.
The mode of use is as follows:
Var Atomicvalue atomic.Value
This type has two exposed pointer methods
/ / the atom reads the value stored in the atomic value instance, returns a value of type interface {}, and accepts no parameters. / / if the value has not been stored through the store method, nilfunc (v * Value) Load () (x interface {}) / / the atom stores a value in the atomic instance, receives a parameter of type interface {} (cannot be nil), and does not return any value func (v * Value) Store (x interface {})
Once the atomic value instance stores a value of a type, then the value stored by Store must be consistent with that type, otherwise a panic will be thrown.
Strictly speaking, once a variable of type atomic.Value is declared, it should not be copied elsewhere. For example, assigning values to other variables as source values, passing them to the function as parameters, returning from the function as a result value, and passing through the channel as element values, all of these will cause values to be copied.
However, pointer-type variables of type atomic.Value do not have this problem, because copying the structure produces not only a copy of the value, but also a copy of the field, so that the value changes caused by concurrency have nothing to do with the original value.
Take a look at the following small example
Func main () {var Atomicvalue atomic.Value Atomicvalue.Store ([] int {1pr 2, 4je 5}) anotherStore (Atomicvalue) fmt.Println ("main:", Atomicvalue)} func anotherStore (Atomicvalue atomic.Value) {Atomicvalue.Store ([] int {6pr 7, Jing 9 Jo 10}) fmt.Println ("anotherStore:", Atomicvalue)}-output---anotherStore: {[6 7 8 9 10]} main: {[1 2 3 4 5]} the difference between atomic operation and mutex
A mutex is a data structure that allows you to perform a series of mutexes. An atomic operation is a mutually exclusive single operation, which means that no other thread can interrupt it. So what's the difference between the atomic operations in the atomic package in the Go language and the synchronization locks provided by the sync package?
First of all, the advantage of atomic operation is that it is lighter, for example, CAS can complete concurrency safe value replacement operation without forming a critical section and creating mutexes. This can greatly reduce the loss of synchronization on program performance.
Atomic operations also have disadvantages. Taking the CAS operation as an example, the practice of using the CAS operation tends to be optimistic, always assuming that the operational value has not been changed (that is, equal to the old value), and the value is replaced as soon as the authenticity of this assumption is confirmed, then the CAS operation is not so easy to succeed when the operational value is changed frequently. On the other hand, the practice of using mutexes tends to be pessimistic, we always assume that there will be concurrent operations to modify the value of the operation, and use the lock to put the relevant operations into the critical area to protect.
So to sum up, the differences between atomic operations and mutexes are:
A mutex is a data structure that allows a thread to execute key parts of a program and complete multiple mutually exclusive operations.
An atomic operation is a single mutually exclusive operation for a value.
Mutexes can be understood as pessimistic locks, shared resources are only used by one thread at a time, other threads block, and then transfer resources to other threads.
The atomic package provides the underlying atomic memory primitives, which are useful for the implementation of synchronization algorithms. These functions must be used very carefully, improper use will increase the cost of system resources, for the application layer, it is best to use the functions provided in the channel or sync package to complete the synchronization operation.
There is also a lot of discussion about the atomic package in the Google mail group, one of which is explained as follows:
Use of this package should be avoided. Or, read the "Atomic Operations" chapter of the C + 11 standard; if you know how to use these operations safely in C + +, you will have the ability to use Go's sync/atomic package safely.
This is the end of the content of "what is the difference between atomic operation and mutex in Go language". Thank you for reading. If you want to know more about the industry, you can follow the website, the editor will output more high-quality practical articles for you!
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.