php协程和goroutine,golang中四种方式实现子goroutine与主协程的同步

如何实现子goroutine与主线程的同步

第一种方式:time.sleep(),这种方式很太死板,就不演示了。

第二种方式:使用channel机制,每个goroutine传一个channel进去然后往里写数据,在再主线程中读取这些channel,直到全部读到数据了子goroutine也就全部运行完了,那么主goroutine也就可以结束了。这种模式是子线程去通知主线程结束。

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

fmt.Println("生产者写入数据", i)

}

close(chanTest)

}()

go func() {

for v := range chanTest {

fmt.Println("\t消费者读出数据", v)

}

chanMain

}()

go func() {

for v := range chanTest {

fmt.Println("\t\t消费者读出数据", v)

}

chanMain

}()

}

第三种方式:使用context中cancel函数,这种模式是主线程去通知子线程结束。

package main

import (

"context"

"fmt"

"time"

)

func gen(ctx context.Context)

dst := make(chan int)

n := 1

go func() {

for {

select {

case

fmt.Println("i exited")

return // returning not to leak the goroutine

case dst

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)

}

第四种方式:sync.WaitGroup模式,Add方法设置等待子goroutine的数量,使用Done方法设置等待子goroutine的数量减1,当等待的数量等于0时,Wait函数返回。

//使用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))

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值