Go Language Practical Notes (13) | Go Concurrency Resource Competition

Source: Internet
Author: User
Tags mutex
This is a creation in Article, where the information may have evolved or changed.

"Go language Combat" reading notes, not to be continued, welcome to sweep code attention flysnow_org to the public, the first time to see follow-up notes. If you feel helpful, share it with your friends and thank you for your support.

Concurrency, there is a resource competition, if two or more goroutine in the absence of mutual synchronization, access to a shared resource, such as simultaneously read and write to the resource, will be in a competitive state, which is the concurrency of resource competition.

Concurrency itself is not complicated, but because of the problem of resource competition, it makes it complicated to develop a good concurrency program, because it can cause a lot of puzzling problems.

123456789101112131415161718192021222324252627282930
 package  mainimport  (  "FMT"   "runtime"   "sync" ) var  (Count int32  wg sync. Waitgroup) func  main   ()   {WG. ADD (2 ) go  inccount () go  Inccount () WG. Wait () fmt. Println (count)}func  inccount  Span class= "params" > ()   {defer  WG. Done () for  i: = 0 ; I < 2 ; i++ {value: = Countruntime. Gosched () Value++count = value}} 

This is a resource competition example, we can run the program several times, we will find that the results may be 2, or 3, or maybe 4. Because the shared resource count variable does not have any synchronization protection, two goroutine will read and write to it, causing the result to be overwritten with the results that have already been computed, so that the result is incorrect, and here we demonstrate the possibility that two goroutine we call G1 and G2 for the time being.

    1. G1 read to count is 0.
    2. Then G1 paused, switched to G2 run, G2 read to count also for 0.
    3. G2 pause, switch to G1,G1 to Count+1,count to 1.
    4. G1 pause, switch to G2,G2 has just gotten to the value 0, to its +1, the last assignment to count or 1
    5. Have you noticed, just G1 to count+1 the result is G2 to cover, two goroutine are +1 or 1

No longer continue to demonstrate, the result has been wrong, two goroutine each other coverage results. We are here to runtime.Gosched() let the current goroutine pause the meaning, to return to the execution queue, let the other waiting goroutine run, the purpose is to let us demonstrate the results of resource competition more obvious. Note that this will also involve CPU problems, multi-core will be parallel, then the effect of resource competition is more obvious.

so our reading and writing of the same resource must be atomized, that is, only one goroutine can read and write to the shared resource at the same time .

The problem of shared resource competition is very complex and difficult to detect, but the go provides us with a tool to help us check, this is the go build -race command. We execute this command in the current project directory, generate a file that can be executed, and then run the executable file to see the printed detection information.

1
Go build-race

Add a -race flag, so that the generated executable program comes with the ability to detect the competition of resources, below we run, but also run at the terminal.

1
./hello

The executable file name that I generated here is hello , so it works, and at this point we look at the results of the terminal output.

123456789101112131415161718192021
➜  hello./hello       ==================warning:data raceread at 0x0000011a5118 by Goroutine 7:  main.inccount ()      /users/xxx/code/go/src/flysnow.org/hello/main.go:25 +0x76previous write at 0x0000011a5118 by Goroutine 6:  Main.inccount ()      /users/xxx/code/go/src/flysnow.org/hello/main.go:28 +0x9agoroutine 7 (running) created at:  Main.main ()      /users/xxx/code/go/src/flysnow.org/hello/main.go:17 +0x77goroutine 6 (finished) created at:  Main.main ()      /users/xxx/code/go/src/flysnow.org/hello/main.go:16 +0x5f==================4found 1 Data race (s)

Look, find a resource competition, even in that line of code out of the problem, are marked out. Goroutine 7 reads the shared resource in line 25, value := count while Goroutine 6 is modifying the shared resource in line 28, count = value and the two goroutine are started from the main function, in 16, 17 lines, through the go keyword.

Now that we know about the issue of shared resource competition, because there are two or more goroutine to read and write to, then we just have to ensure that only one goroutine read and write is not available, we will look at the traditional solution to the competition of resources-the resource lock.

The go language provides some of the functions in the atomic package and the Sync Pack to synchronize the shared resources, let's look at the atomic package first.

12345678910111213141516171819202122232425262728293031
 package  mainimport  (   "sync"  ) var  (count int32  wg sync. Waitgroup) func  main   ()   {WG. ADD (2 ) go  inccount () go  Inccount () WG. Wait () fmt. Println (count)}func  inccount  Span class= "params" > ()   {defer  WG. Done () for  i: = 0 ; I < 2 ; i++ {value: = Atomic. LoadInt32 (&count) runtime. Gosched () value++atomic. StoreInt32 (&count,value)}} 

Note here atomic.LoadInt32 and atomic.StoreInt32 two functions, a read the value of the Int32 type variable, one is to modify the value of the Int32 type variable, both are atomic operations, go has helped us to use the lock mechanism at the bottom, to ensure the synchronization of shared resources and security, so we can get the correct results , we can then use the Resource Competition detection Tool go build -race to check, and will not prompt a problem.

Atomic package also has a lot of atomic functions can guarantee concurrency access to modify the problem, such as the function atomic.AddInt32 can be directly on a int32 type of variables to modify, on the basis of the original value of how much more function, is also atomic, here no longer an example, we can try.

Although the atomic can solve the problem of resource competition, but the comparison is relatively simple, the supported data types are also limited, so the Go language also provides a sync package, the Sync package provides a mutex lock, which gives us the flexibility to control which code, At the same time can only have a goroutine access, by the sync mutex control of the code range, called the critical section, critical section of the code, the same time, can only another goroutine access. Just for that example, we can change that.

123456789101112131415161718192021222324252627282930313233
 package  mainimport  (  "FMT"   "runtime"   "sync" ) var  (Count int32  wg sync. Waitgroupmutex sync. Mutex) func  main   ()   {WG. ADD (2 ) go  inccount () go  Inccount () WG. Wait () fmt. Println (count)}func  inccount  Span class= "params" > ()   {defer  WG. Done () for  i: = 0 ; I < 2 ; i++ {Mutex. Lock () Value: = Countruntime. Gosched () Value++count = Valuemutex. Unlock ()}} 

instance, a new mutex is declared, which mutex sync.Mutex has two methods, one is that the mutex.Lock() area between the two is a mutex.Unlock() critical section, and the Code for the critical section is safe.

In the example we first call mutex.Lock() the code that has the competition resource lock, so when a goroutine into this area, the other goroutine will not come in, can only wait, until the call to mutex.Unlock() release the lock.

This is a more flexible approach, allowing code writers to arbitrarily define the range of code that needs to be protected, which is the critical section. In addition to atomic functions and mutexes, go also provides us with the ability to sync more easily in multiple goroutine, which is channel Chan, which we'll talk about in the next chapter.

"Go language Combat" reading notes, not to be continued, welcome to sweep code attention flysnow_org to the public, the first time to see follow-up notes. If you feel helpful, share it with your friends and thank you for your support.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.