Four ways to achieve synchronization between sub-goroutine and main coroutine in golang

How to achieve synchronization between child goroutine and main thread

  • The first method: time.sleep(), this method is too rigid and will not be demonstrated.
  • The second way: using the channel mechanism, each goroutine passes a channel in and writes data into it, and reads these channels in the main thread, until all the data is read and the sub-goroutines are all run, then the main goroutine also It's over. In this mode, the child thread notifies the main thread of the end.
package main

import (
    "fmt"
)

func main() {
    var chanTest = make(chan int)
    var chanMain = make(chan int)

    go func() {
        for i := 0; i < 20; i++ {
            chanTest <- i
            fmt.Println("生产者写入数据", i)
        }
        close(chanTest)
    }()

    go func() {
        for v := range chanTest {
            fmt.Println("\t消费者读出数据", v)

        }

        chanMain <- 666
    }()

    go func() {
        for v := range chanTest {
            fmt.Println("\t\t消费者读出数据", v)

        }
        chanMain <- 666

    }()

    <-chanMain
    <-chanMain

}
  • The third way: use the cancel function in the context, this mode is the main thread to notify the end of the child thread.
package main

import (
    "context"
    "fmt"
    "time"
)

func gen(ctx context.Context) <-chan int {
    dst := make(chan int)
    n := 1
    go func() {
        for {
            select {
            case <-ctx.Done():
                fmt.Println("i exited")
                return // returning not to leak the goroutine
            case dst <- n:
                n++
            }
        }
    }()
    return dst
}

func test() {
    
    ctx, cancel := context.WithCancel(context.Background())
    defer cancel() // cancel when we are finished consuming integers
    intChan := gen(ctx)
    for n := range intChan {
        fmt.Println(n)
        if n == 5 {
            break
        }
    }
}
func main() {
    test()
    time.Sleep(time.Hour)
}
  • The fourth method: sync.WaitGroup mode, the Add method sets the number of waiting child goroutines, and the Done method is used to set the number of waiting child goroutines minus 1. When the waiting number is equal to 0, the Wait function returns.
//使用golang中sync.WaitGroup来实现协程同步  
  
package main  
  
import (  
    "fmt"  
    "net/http"  
    "io/ioutil"  
    "time"  
    "os"  
    "sync"  
)  
  
var waitGroup = new(sync.WaitGroup)  
func download(i int ){  
        url := fmt.Sprintf("http://pic2016.ytqmx.com:82/2016/0919/41/%d.jpg", i)  
        fmt.Printf("开始下载:%s\n", url)  
        res,err := http.Get(url)  
        if err != nil || res.StatusCode != 200{  
            fmt.Printf("下载失败:%s", res.Request.URL)  
        }  
        fmt.Printf("开始读取文件内容,url=%s\n", url)  
        data ,err2 := ioutil.ReadAll(res.Body)  
        if err2 != nil {  
            fmt.Printf("读取数据失败")  
        }  
  
        ioutil.WriteFile(fmt.Sprintf("pic2016/1_%d.jpg", i), data, 0644)  
        //计数器-1  
        waitGroup.Done()  
}  
  
func main()  {  
    //创建多个协程,同时下载多个图片  
    os.MkdirAll("pic2016", 0666)  
    now := time.Now()  
  
    for i :=1; i<24; i++ {  
        //计数器+1  
        waitGroup.Add(1)  
        go download(i)  
    }  
  
    //等待所有协程操作完成  
    waitGroup.Wait()  
    fmt.Printf("下载总时间:%v\n", time.Now().Sub(now))  
} 
http://www.njb8631.cn/
http://www.kzo4326.cn/
http://www.tso8557.cn/
http://www.nwm1536.cn/
http://www.tae4138.cn/
http://www.dxc3579.cn/
http://www.ffp5727.cn/
http://www.lhb4836.cn/
http://www.xdi0113.cn/
http://www.bpa2365.cn/
http://www.fks8445.cn/
http://www.aht8537.cn/
http://www.cun5054.cn/
http://www.gdk7028.cn/
http://www.ypk8666.cn/
http://www.wan2959.cn/
http://www.sit9945.cn/
http://www.zmj4226.cn/
http://www.ccn6233.cn/
http://www.jck8045.cn/
http://www.ckk6213.cn/
http://www.mak1390.cn/
http://www.vii0197.cn/
http://www.pwj5001.cn/
http://www.wvh4263.cn/
http://www.mvg0339.cn/
http://www.yif9712.cn/
http://www.jta0960.cn/
http://www.omx8816.cn/
http://www.nlc4773.cn/
http://www.dep9137.cn/
http://www.vlq7732.cn/
http://www.umg2515.cn/
http://www.kog1435.cn/
http://www.nxf9936.cn/
http://www.hqh7518.cn/
http://www.hij5984.cn/
http://www.vui9639.cn/
http://www.fzl7156.cn/
http://www.wue0833.cn/
http://www.dye6768.cn/
http://www.ryh7899.cn/
http://www.lij0467.cn/
http://www.epv8502.cn/
http://www.lru8400.cn/
http://www.mtr5072.cn/
http://www.kbs9896.cn/
http://www.qfk7654.cn/
http://www.myb6827.cn/
http://www.tcr0461.cn/
http://www.xua4102.cn/
http://www.tzn6024.cn/
http://www.kme4313.cn/
http://www.bnb6875.cn/
http://www.yio4898.cn/
http://www.yat8046.cn/
http://www.mtl1611.cn/
http://www.ltz6047.cn/
http://www.wsa2392.cn/

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325811154&siteId=291194637