php协程和goroutine,golang中四种方式实现子goroutine与主协程的同步
如何實(shí)現(xiàn)子goroutine與主線程的同步
第一種方式:time.sleep(),這種方式很太死板,就不演示了。
第二種方式:使用channel機(jī)制,每個(gè)goroutine傳一個(gè)channel進(jìn)去然后往里寫(xiě)數(shù)據(jù),在再主線程中讀取這些channel,直到全部讀到數(shù)據(jù)了子goroutine也就全部運(yùn)行完了,那么主goroutine也就可以結(jié)束了。這種模式是子線程去通知主線程結(jié)束。
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("生產(chǎn)者寫(xiě)入數(shù)據(jù)", i)
}
close(chanTest)
}()
go func() {
for v := range chanTest {
fmt.Println("\t消費(fèi)者讀出數(shù)據(jù)", v)
}
chanMain
}()
go func() {
for v := range chanTest {
fmt.Println("\t\t消費(fèi)者讀出數(shù)據(jù)", v)
}
chanMain
}()
}
第三種方式:使用context中cancel函數(shù),這種模式是主線程去通知子線程結(jié)束。
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方法設(shè)置等待子goroutine的數(shù)量,使用Done方法設(shè)置等待子goroutine的數(shù)量減1,當(dāng)?shù)却臄?shù)量等于0時(shí),Wait函數(shù)返回。
//使用golang中sync.WaitGroup來(lái)實(shí)現(xiàn)協(xié)程同步
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("開(kāi)始下載:%s\n", url)
res,err := http.Get(url)
if err != nil || res.StatusCode != 200{
fmt.Printf("下載失敗:%s", res.Request.URL)
}
fmt.Printf("開(kāi)始讀取文件內(nèi)容,url=%s\n", url)
data ,err2 := ioutil.ReadAll(res.Body)
if err2 != nil {
fmt.Printf("讀取數(shù)據(jù)失敗")
}
ioutil.WriteFile(fmt.Sprintf("pic2016/1_%d.jpg", i), data, 0644)
//計(jì)數(shù)器-1
waitGroup.Done()
}
func main() {
//創(chuàng)建多個(gè)協(xié)程,同時(shí)下載多個(gè)圖片
os.MkdirAll("pic2016", 0666)
now := time.Now()
for i :=1; i<24; i++ {
//計(jì)數(shù)器+1
waitGroup.Add(1)
go download(i)
}
//等待所有協(xié)程操作完成
waitGroup.Wait()
fmt.Printf("下載總時(shí)間:%v\n", time.Now().Sub(now))
}
總結(jié)
以上是生活随笔為你收集整理的php协程和goroutine,golang中四种方式实现子goroutine与主协程的同步的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 我叫mt4最后一块石碑在哪
- 下一篇: 中国移动董事长杨杰:今年收入规模超万亿应