上海城隍庙景点介绍,自助建站网站seo公司,c#网站开发视频教程 高清,建网站平台要多少钱golang中的并发是函数相互独立运行的能力。Goroutines是并发运行的函数。Golang提供了
如何实现go协程 只需要在函数前面加上go即可
go task()package mainimport (fmttime
)func show(msg string) {for i : 0; i 5; i {fmt.Printf(msg: …golang中的并发是函数相互独立运行的能力。Goroutines是并发运行的函数。Golang提供了
如何实现go协程 只需要在函数前面加上go即可
go task()package mainimport (fmttime
)func show(msg string) {for i : 0; i 5; i {fmt.Printf(msg: %v\n, msg)time.Sleep(time.Microsecond * 1000)}
}func main() {go show(go show) //开辟goroutines中运行show(haha) //这个会在main函数的goroutines中运行//注意协程是主进程的守护进程主进程结束协程就结束了不管运没运行完fmt.Println(end..........)
}
channel 它是一个数据管道可以往里面写数据从里面读数据。 channel 是 goroutine 之间数据通信桥梁而且是线程安全的。 channel 遵循先进先出原则。 写入读出数据都会加锁。 channel 可以分为 3 种类型
只读 channel单向 channel只写 channel单向 channel可读可写 channel
channel 还可按是否带有缓冲区分为
带缓冲区的 channel定义了缓冲区大小可以存储多个数据不带缓冲区的 channel只能存一个数据并且只有当该数据被取出才能存下一个数据
unbuffered:make(channel int)
buffered:make(channel int,10)package mainimport (fmtmath/randtime
)var channeltest make(chan int)func show(msg string) {value : rand.Intn(10)channeltest - value // 往管道中写数据}func main() {defer close(channeltest) // 关闭管道go show(go show) //开辟goroutines中运行time.Sleep(time.Second * 1)value : -channeltest //从channel中获取数据fmt.Printf(value: %v\n, value)//注意协程是主进程的守护进程主进程结束协程就结束了不管运没运行完fmt.Println(end..........)
}waitgroup实现同步 类似于.net中的task wait你可以取消下面wg 的试试看两者的区别我们添加完wg后发现a以及b函数都执行完毕
package mainimport (fmtsynctime
)var wg sync.WaitGroupfunc a() {defer wg.Done()for i : 0; i 10; i {fmt.Println(a函数)time.Sleep(time.Microsecond * 100)}
}func b() {defer wg.Done() //别忘了在一次执行完毕后运行这个函数for i : 0; i 10; i {fmt.Println(b函数)time.Sleep(time.Microsecond * 100)}
}func main() {wg.Add(1) //在每一个go之前执行这个行数go a() //开辟goroutines中运行wg.Add(1)go b()wg.Wait()//注意协程是主进程的守护进程主进程结束协程就结束了不管运没运行完fmt.Println(end..........)
}Mutex 锁用来解决同时访问全局变量
package mainimport (fmtruntimesynctime
)var wg sync.WaitGroup
var value int 100
var lock sync.Mutexfunc a() {defer wg.Done()for i : 0; i 100; i {lock.Lock()value 1lock.Unlock()fmt.Println(a)time.Sleep(time.Microsecond * 100)}
}func b() {defer wg.Done()for i : 0; i 100; i {lock.Lock()value - 1lock.Unlock()fmt.Println(a--)time.Sleep(time.Microsecond * 100)}
}func main() {fmt.Printf(runtime.NumCPU(): %v\n, runtime.NumCPU())runtime.GOMAXPROCS(8) //最大并发wg.Add(1)go a()wg.Add(1) //开辟goroutines中运行go b()wg.Wait()fmt.Println(end..........)fmt.Printf(value: %v\n, value)
}runtime包
runtime.Gosched() 让出CPU重新等待安排任务
package mainimport (fmtruntime
)func a() {for i : 0; i 2; i {fmt.Println(a函数)}}func main() {fmt.Printf(runtime.NumCPU(): %v\n, runtime.NumCPU())runtime.GOMAXPROCS(8) //最大并发go a() //开辟goroutines中运行for i : 0; i 2; i {runtime.Gosched() //让出CPU执行A函数fmt.Printf(i: %v\n, i)}fmt.Println(end..........)
}runtime.Goexit() 退出协程runtime.GOMAXPROCS(8) 最大并发
select Switch
select是Go中的一个控制结构类似于Switch语句用于处理异步IO操作。select会监听语句中channel的读写操作当case中channel读写操作为非阻塞状态时将会触发相应的动作select中的case语句必须是一个channel操作select中的default自居总是可运行的如果有多个case都可以运行select会随机公平的选出一个执行其他不会执行如果没有可执行的case语句且有default语句那么会执行default如果没有可运行的case语句且没有default语句select将阻塞知道某个case可以运行
package mainimport (fmttime
)var valueint make(chan int)
var valurstring make(chan string)func main() {//关闭通道后会读取类型默认值如int默认值为0go func() {valueint - 100valurstring - hahadefer close(valueint)defer close(valurstring)}()for {select {case r : -valueint:fmt.Printf(valueint: %v\n, r)case r : -valurstring:fmt.Printf(valurstring: %v\n, r)default:fmt.Println(default .....)}time.Sleep(time.Second)}
}
ticker ticker会一直运行timer只运行一次
package mainimport (fmtruntimetime
)var valueint make(chan int)func main() {ticker : time.NewTicker(time.Second)//关闭通道后会读取类型默认值如int默认值为0go func() {//每秒钟随机的往通道插入数据for _ range ticker.C {select {case valueint - 1:case valueint - 2:case valueint - 3:}}}()var sum intfor v : range valueint {fmt.Printf(v: %v\n, v)sum vif sum 10 {runtime.Goexit()}}
}