Golang Shared Memory

Source: Internet
Author: User

In Golang languages, inter-process communication can use shared memory, which is the sync package, in addition to using the channel.

Q-1

Package Mainimport ("FMT", "Time") Func main () {for i: = 1; i < 6; i++ {go func (x int) {time. Sleep (time. Second) fmt. Println ("First", X, "Goroutine Execution End")} (i)}fmt. Println ("Main goroutine execution End")}

There is no doubt that the above code will only output: "The main goroutine execution end", and not the output sub-goroutine execution end, because, once the main process is completed, the entire session will be finished.

  

Sync Group Wait

There are three methods commonly used in the Sync Pack: ADD (num int), done (), Wait ()

Sync will maintain a counter-like thing inside, through the Add method to increase the value of the counter, add the parameter num, by doing to reduce the value of the counter, only reduce the 1;wait method at a time can cause the main process to block, only to the internal counter value of 0 o'clock, blocking will be solved.

Use the following:

Package Mainimport ("FMT" "Sync" "Time") Func main () {var wg sync. Waitgroupfor I: = 1; I < 6; i++ {WG. Add (1)//Counter plus 1go func (x int) {time. Sleep (time. Second) fmt. PRINTLN ("section", X, "Goroutine execution End") WG. Done ()//goroutine execution, counter minus 1} (i)}WG. Wait ()  //counter is blocked at 0 when the counter becomes 0, blocking the FMT. Println ("Main goroutine execution End")}

Note: The number of timers added must be less than the number of timer reductions, otherwise a deadlock will be thrown.

For example, the counter value is increased by 10, but only 9 counter reduction, the remaining counter, the value of the counter is always not 0, the main process has been waiting to form a deadlock. However, fewer counters can be larger than the value of the counter and can end the blocking of the main process prematurely.

  

Q-2

Take a look at the following piece of code, try to make sum plus 1 for each of the two loops, and perform 1000 times, at first glance, think the result is the end result of Sum is 2000, but after the actual execution, the result is not 2000.

Package Mainimport ("FMT" "Sync") func main () {var wg sync. Waitgroupwg.add (2) var sum int = 0go func () {for i: = 0; i <; i++ {SUM++}WG. Done ()} () go func () {for i: = 0; i <; i++ {SUM++}WG. Done ()} () WG. Wait () fmt. Println (SUM)}

  

Sync Mutual Exclusion Lock

Sync mutex has two common methods, lock () plus lock, Unlock () unlocked. Locks can no longer be locked with lock, and can only be locked when unlock unlocked. This is very well understood.

If you unlock an unlocked resource, a panic exception is thrown.

You can lock one resource in one goroutine and unlock that resource in another goroutine.

Examples of use are:

Package Mainimport ("FMT" "Sync") func main () {var wg sync. Waitgroupvar Mutex sync. Mutexwg.add (2) var sum int = 0go func () {for i: = 0; i <; i++ {mutex. Lock ()//Lock Sum++mutex. Unlock ()//unlock}WG. Done ()} () go func () {for i: = 0; i <; i++ {mutex. Lock ()//locking Sum++mutex. Unlock ()//unlock}WG. Done ()} () WG. Wait () fmt. Println (SUM)}

  

Sync read and write mutex (read-write lock)

Allows simultaneous reading of the same resource, but cannot be written at the same time, nor can it be read and written on one side.

If a resource is added to a lock, then no additional locks can be added, including write locks, which can only be unlocked after the write lock is unlocked. If a resource is read-locked, the resource can still be read-locked, but cannot write locks, and must wait for the read lock to be released before the lock is added.

Sync. There are four common methods of Rwmutex:

Lock () Add write lock, Unlock () Cancel write lock, Rlock () read lock, Runlock () release read lock

Examples of Use:

Package Mainimport ("FMT" "Sync" "Time") var Rwmutex sync. Rwmutex//Define a read/write mutex//Note that the group wait for delivery is a pointer form of Func WRITEDATA (WG *sync. Waitgroup, id int) {rwmutex.lock ()//Add write lock FMT. Println ("Add section", ID, "write lock") for I: = 0; I < 5; i++ {fmt. Println ("write operation") time. Sleep (time. Second)}fmt. Println ("Release first", ID, "write lock") Rwmutex.unlock ()//release write lock WG. Done ()}func ReadData (WG *sync. Waitgroup, id int) {rwmutex.rlock ()//Read lock FMT. Println ("Add section", ID, "read lock") for I: = 0; I < 5; i++ {fmt. PRINTLN ("read operation") time. Sleep (time. Second)}fmt. Println ("Release first", ID, "read lock") Rwmutex.runlock ()//release read lock WG. Done ()}func main () {var wg sync. Waitgroupfor I: = 1; I < 3; i++ {WG. ADD (1) Go WriteData (&WG, i)}for i: = 1; I < 4; i++ {WG. ADD (1) Go ReadData (&WG, i)}wg. Wait () fmt. Println ("Main program Execution Complete")}

After running, it will be found that only one write lock, only after the write unlock, only allow the addition of other locks, if it is read lock, you can read the lock.

Q-3

Package Mainimport ("FMT" "Sync") func demo () {fmt. Println ("Run demo function")}func main () {var wg sync. Waitgroupfor I: = 0; I < 10; i++ {WG. ADD (1) go func () {demo () WG. Done ()} ()}wg. Wait () fmt. Println ("Main program End")}

After this example code runs, it outputs 10 "run demo functions" because there are 10 goroutine and each goroutine runs 1 times.

Now the demand is: although there are 10 goroutine, but I want only one goroutine to execute the demo function, if a goroutine executed the demo function, the other goroutine will ignore the demo function, not to execute the demo, Ensure that the demo function is executed only once.

Sync.once initialization

Sync. Once is used to solve the above problem: Once function is called multiple times, but only once, Once only one method->once.do (func), to do in a function, in the first execution of Once.do (), the execution of the incoming Func, After executing the once.do (), the incoming Func is no longer executed.

Examples are as follows:

Package Mainimport ("FMT" "Sync") func demo () {fmt. Println ("Run demo function")}func main () {var wg sync. Waitgroupvar once sync. Oncefor I: = 0; I < 10; i++ {WG. ADD (1) go func () {once. Do (demo)//Pay attention not to write once. Do (demo ()), which writes the results of the demo () to Dowg.done ()} ()}wg. Wait () fmt. Println ("Main program End")}

This will not execute multiple demo (), and only output once "Run Demo function"

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.