首页 > 其他 > 详细

Go goroutine chanel

时间:2020-07-04 09:18:55      阅读:53      评论:0      收藏:0      [点我收藏+]

 


使用go关键字启动一个goroutine
程序员唯一需要做的
是把任务封装成一个函数
程序启动之后会创建一个主goroutine去执行(main也是一个goroutine)

package main

import(
    "fmt"
    "sync"
    "runtime"
)

var wg sync.WaitGroup  //計數器

func print(i int) {
    defer wg.Done()   //任務完成,計數器-1
    fmt.Println(i)
}

func main() {
    runtime.GOMAXPROCS(1) //默認CPU邏輯核心數,默認跑滿整個CPU
    // wg.Add(10) 
    for i:=0; i<100; i++{
        wg.Add(1)    //啟動任務,計數器+1
        go print(i)  //啟動一個線程
    }
    
    wg.Wait()   // 等待wg的計數器減為0
}

goroutine调度模型

GMP
m:n 把m个goroutine分配给n个操作系统线程去执行
goroutine初始栈的大小是2k
runtime.GOMAXPROCS(1) 可以修改n的值

 

现实中并发的目的是执行任务
比如第一种任务,每个任务的执行都依赖上一个任务的结果,这种并发是没有意义的
任务链:f1() -> f2() - > f3()
比如第二种任务,某个任务的执行依赖多个任务的结果,这多个任务可以并发执行
任务链:f1()|f2()|f3() -> f4()

虽然可以使用共享内存进行数据交换,但是共享内存在不同的goroutine中容易发生竞态问题。为了保证数据交换的正确性,必须使用互斥量对内存进行加锁,这种做法势必造成性能问题。

Go语言的并发模型是CSP(Communicating Sequential Processes),
提倡通过通信共享内存而不是通过共享内存而实现通信。

 

var b chan int //声明管道
b = make(chan int) //给管道开辟空间,无缓冲
b = make(chan int, 5) //带缓冲的通道,可预存5个值,存满后再放就阻塞

b <- 2 //给通道放值


var n int; n = <- b //从通道取值,方式一

n := <-b   // 从通道取值,方式二
<- b //取出值扔掉

close(b) //关闭通道,关闭分为两端,读的一端和写的一端。例如: f1函数写,f1里面close,表示不能向管道里写了,但是能读。 f2函数读,f2里面close,表示不能从f2里面读了,但是能向f2里面写。

在运行中,确定不用了,要手动关闭通道。不关闭很容易造成deadlock

for i:= range b {
fmt.Println(i) //从通道里循环取值
}

小的值扔通道里直接扔值,大的值扔指针


//开启goroutine将0~100的数发送到ch1中
//开启goroutine从ch1中接收值,将该值的平方发送到ch2中

Go goroutine chanel

原文:https://www.cnblogs.com/staff/p/13233476.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!