Concurrency security means that multiple concurrent bodies access the same shared data within the same period of time, and the shared data can be processed correctly.
Concurrent programming in many languages is easy to make errors when modifying a variable at the same time, because the operation is not atomic, such as the variable used by an addition operation is modified, resulting in errors in the calculation result, which is typical for statistics on commodity inventory.
Personally, I suggest that all shared variables are usedchannel
,becausechannel
A mutex lock is used in the source code, which is concurrently safe.
We can not use it, but we must not misunderstand it. We are not panic when we have food in our hands.
Examples of concurrency insecurity
Arrays are concurrently unsafe, we need to know before the example begins.append
The behavior of the function: the length is enough in the original arraycap
Append functions to addlen
, if the length is not enough, the capacity expansion will be triggered and a new array will be applied for.cap
Double the assignment migration.
Therefore, in this process, if you only discuss the expansion operation, there may be cases of simultaneously applying and assigning values, resulting in the missed data of an expansion increase.
var s []int func appendValue(i int) { s = append(s, i) } func main() { for i := 0; i < 10000; i++ { //10000 coroutines add slices at the same time go appendValue(i) } (2) (len(s)) }
For example,10000
A coroutine adds data to the slice at the same time. You can try to run it, and the printed one must be not10000
。
- The same resource for the above concurrent operation is calledCritical Zone。
- Because there is data competition in concurrent operations, the data value is accidentally rewritten, and the final result does not match the expected ones. This problem is collectively calledCompetition issues。
It is common in controlling commodity inventory reduction, controlling balance increase and decrease. So is there any way to solve the competition problem?
- Mutex: When accessing a critical area, there is only one
goroutine
Available to access. - Atomic operations: Let certain operations become atoms, this follow-up discussion.
These two ideas run through countless high-concurrency/distributed solutions, whether they are used in a process application or implemented with the help of some third-party means, such as middleware. The Dugu Nine Sword Forest must be remembered firmly.
Mutex lock
Go
The usage of mutex locks in languages is as follows:
var lock //Mutual Exclusion Lock() // Add locks = append(s, i) () //Unlock
Adding a mutex before and after accessing the critical area can ensure that there will be no concurrency problems.
We modified it or the previous one4.7.1
Examples of adding mutex to it.
var s []int var lock appendValueSafe := func(i int) { () s = append(s, i) () } for i := 0; i < 10000; i++ { //10000 coroutines add slices at the same time go appendValueSafe(i) } (2) (len(s))
- Shared variables
s
The write operation plus a mutex lock ensures that there is only one at the same timegoroutine
Modify content. - After locking and before unlocking, there is only one access at the same time, regardless of read or write.
- No matter how many times it is output
10000
, there will be no competition problems again. - Note:If there is a concurrent read operation while writing, in order to prevent half of the data being read, you need to add a lock to the read operation.
Read and write lock
Mutex locks are completely mutually exclusive. There will be no problem if concurrent reads are not modified. There is no need to add locks during concurrent reads, otherwise the efficiency will be lower.
usage:
rwlock //Read lock() () //Write lock() ()
Concurrent reading is not mutually exclusive, and when a write lock is acquired, all other locks are waiting. The formula: reading is not mutually exclusive, reading is mutually exclusive, and writing is mutually exclusive. For specific calculations of speed, see the source code of 4.7.3. If you are interested, you can change the comment position and see that the efficiency has been significantly improved.
summary
- Several nouns have been learned: critical section, competitive problem, mutex lock, atomic operation, read and write lock.
- Mutex:
, Read and write lock:
All
sync
Packed. - Read and write locks are more efficient than mutex locks.
Question: Is it okay to just add a lock? Why?
Summarize
This is the article about how to improve the efficiency of Go concurrency and lock. For more information about Go concurrency and lock, please search for my previous articles or continue browsing the relevant articles below. I hope everyone will support me in the future!