Package Main;import ("FMT" "Sync" "Runtime" "Time")//locking, note that the lock is to be passed in as a pointer, otherwise it is just a copy of the Func total1 (Num *int, mu *sync. Mutex, CH chan bool) {mu. Lock (); for i: = 0; i < 1000; i++ {*num + = i;} Ch <-true;mu. Unlock ();} No lock func total2 (num *int, CH chan bool) {for I: = 0; i <; i++ {*num + = i;} CH <-true;} Lock, unlock, and Rlock, Runlock cannot be nested using the Func total3 (Num *int, RWMU *sync. Rwmutex, CH Chan bool) {for I: = 0; i <; i++ {RWMU. Lock (); *num + = I;rwmu. Unlock (); if (i = = 500) {//Read lock RWMU. Rlock (); fmt. Print (*num, ""); Rwmu. Runlock ();}} CH <-true;} Func printnum (num int, cond *sync. Cond) {Cond. L.lock (); if num < 5 {//num is less than 5 o'clock, enter the wait state cond. Wait ();} More than 5 of the normal output FMT. PRINTLN (num); cond. L.unlock ();} Func Main () {//once.do () guarantees that multiple calls are performed only once Once: = Sync. Once{};ch: = Make (chan bool, 3); for I: = 0; I < 3; i++ {go func (n int) {once. Do (func () {//is only executed once because the closure refers to the variable n and the last value is 2fmt. PRINTLN (n)});//Send True to Chan, indicating that execution is complete ch <-true;} (i);} For I: = 0; I < 3; i++ {//Read three Chan, if the above three times do not finish will be blocked <-ch;} A mutex that guarantees that only one access object at a time can have a mutex: =Sync. MUTEX{};CH2: = Make (chan bool, 20);//Use multicore, otherwise the result will be the same runtime. Gomaxprocs (runtime. NUMCPU ()); NUM1: = 0;num2: = 0;for I: = 0; I < 10; i++ {Go total1 (&num1, &mutex, CH2);} For I: = 0; I < 10; i++ {Go total2 (&num2, CH2);} For I: = 0; I < 20; i++ {<-ch2;} Will find that NUM1 and num2 calculated the results are not the same//and NUM1 The result is correct, because Total2 is not locked, resulting in multiple goroutine operation num when data Chaos FMT. Println (NUM1, num2);//Read and write lock, read lock, and read unlock, let multiple goroutine simultaneously read object Rwmutex: = Sync. RWMUTEX{};CH3: = Make (chan bool, ten); num3: = 0;for I: = 0; I < 10; i++ {Go total3 (&num3, &rwmutex, CH3);} For I: = 0; I < 10; i++ {<-ch3;} Fmt. Println (num3);//group Waits, waiting for a group of Goroutine to end WG: = Sync. waitgroup{};//Add Counter WG. ADD (); for i:= 0; i< 10; i++ {go func (n int) {FMT. Print (N, "");//here indicates that the Goroutine executes the completion WG. Done ();} (i);} Wait for all threads to execute the completion WG. Wait (); fmt. Println ("");//Condition wait mutex2: = sync. MUTEX{};//uses the lock to create a condition to wait for cond: = Sync. Newcond (&MUTEX2); for I: = 0; I < 10; i++ {Go printnum (I, cond);} Time. Sleep (time. Second * 1);//Wait a second, we first wake up a wait, output a digital cond. L.lock () cond. Signal ();Cond. L.unlock (); time. Sleep (time. Second * 1);//After one second, wake up all, output the remaining four cond. L.lock () cond. Broadcast (); cond. L.unlock (); time. Sleep (time. Second * 1);}
Go Language Sync Pack learning (Mutex, Waitgroup, Cond)