初识Go(8)

并发

goroutine
goroutine 是 Go 并行设计的核心。goroutine 说到底其实就是线程,但是他比线程更小,十
几个 goroutine 可能体现在底层就是五六个线程,Go 语言内部帮你实现了这些 goroutine
之间的内存共享。执行 goroutine 只需极少的栈内存(大概是 4~5KB),当然会根据相应的数
据伸缩。也正因为如此,可同时运行成千上万个并发任务。 goroutine 比 thread 更易用、更高
效、更轻便。goroutine 是通过 Go 的 runtime 管理的一个线程管理器

package main
import (
"fmt"
"runtime"
)
func say(s string) {
for i := 0; i < 5; i++ {
runtime.Gosched()
fmt.Println(s)
}
}
func main() {
go say("world") //开一个新的 Goroutines 执行
say("hello") //当前 Goroutines 执行
}
// hello world hello world ^^^^^^^
很容易实现了并发

Channel
goroutine 运行在相同的地址空间,因此访问共享内存必须做好同步。那么 goroutine 之间如
何进行数据的通信呢,Go 提供了一个很好的通信机制 channel。 channel 可以与 Unix shell
中的双向管道做类比:可以通过它发送或者接收值。这些值只能是特定的类型:channel 类
型。定义一个 channel 时,也需要定义发送到 channel 的值的类型。注意,必须使用 make
创建 channel:
ci := make(chan int)
cs := make(chan string)
cf := make(chan interface{})

channel 通过操作符<-来接收和发送数据
ch <- v // 发送 v 到 channel ch.
v := <-ch // 从 ch 中接收数据,并赋值给 v
写个小例子:
func sum(a []int, c chan int) {
sum := 0
for _, v := range a {
sum += v
}
c <- sum // send sum to c
}
func main() {
a := []int{7, 2, 8, -9, 4, 0}
c := make(chan int)
go sum(a[:len(a)/2], c)
go sum(a[len(a)/2:], c)
x, y := <-c, <-c // receive from c
fmt.Println(x, y, x + y)
}

Buffered Channels
上面我们介绍了默认的非缓存类型的 channel,不过 Go 也允许指定 channel 的缓冲大小,
很简单,就是 channel 可以存储多少元素。ch:= make(chan bool, 4),创建了可以存储 4 个
元素的 bool 型 channel。在这个 channel 中,前 4 个元素可以无阻塞的写入。 当写入第 5 个
元素时,代码将会阻塞,直到其他 goroutine 从 channel 中读取一些元素,腾出空间。
ch := make(chan type, value)
value == 0 ! 无缓冲(阻塞)
value > 0 ! 缓冲(非阻塞,直到 value 个元素)

c := make(chan int, 2)//修改 2 为 1 就报错,修改 2 为 3 可以正常运行
c <- 1
c <- 2
fmt.Println(<-c)
fmt.Println(<-c)

Range 和 Close
func fibonacci(n int, c chan int) {
x, y := 1, 1
for i := 0; i < n; i++ {
c <- x
x, y = y, x + y
}
close(c)//关闭chan,之后就无法发送数据了
}
func main() {
c := make(chan int, 10)
go fibonacci(cap(c), c)//cap,chan的缓冲大小
for i := range c {//能够不断从chan里读取数据,知道chan关闭
fmt.Println(i)
}
}
记住应该在生产者的地方关闭 channel,而不是消费的地方去关闭它,这样容易引起 panic
另外记住一点的就是 channel 不像文件之类的,不需要经常去关闭,只有当你确实没有任
何发送数据了,或者你想显式的结束 range 循环之类的

selsect
我们上面介绍的都是只有一个 channel 的情况,那么如果存在多个 channel 的时候,我们
该如何操作呢,Go 里面提供了一个关键字 select,通过 select 可以监听 channel 上的数据
流动。
select 默认是阻塞的,只有当监听的 channel 中有发送或接收可以进行时才会运行,当多
个 channel 都准备好的时候,select 是随机的选择一个执行的。我们还可以利用select来设置超时,
因为程序一旦阻塞就一直停在那里,所以我们需要设置阻塞超时。
func main() {
c := make(chan int)
o := make(chan bool)
go func() {
for {
select {
case v := <- c:
println(v)
case <- time.After(5 * time.Second):
println("timeout")
o <- true
break
}
}
}()
<- o
}

时间: 2024-10-16 12:23:32

初识Go(8)的相关文章

初识Python,望君多多关照

在学习Python之前,我们接触过数据结构和网页制作.前者让我们学习如何把C语言运用的更加整齐规范,而后者让我们亲身学习如何运用所学,制作一个静态网页.通过这些课程的学习,让我对C语言产生了比较大的压力,以至于对编程.对这学期的Python课程都有一种如临大敌的感觉. 但是真的学习了这门课程,体会了编码过程中的一些固定运用方法和套路之后,也许过程中对这门课程隐隐约约产生了一点点朦胧的感觉,仿佛他也并没有想象中的那么困难,起码现在的学习让我认为,他可能没有C语言那么繁琐和麻烦.当然,以一个初学者的

初识数组排序!!!!

<!doctype html> <html lang="en"> <head> <meta charset="UTF-8"> <title>初识数组排序</title> <!--调试成功--> <style type="text/css"> *{ padding:0; margin: 0; } li,ul{ list-style: none; } #p

初识操作系统和linux

初识操作系统和linux 1.计算机系统由硬件系统和软件系统两大部分组成:是一种能接收和存储信息,并按照存储在其内部的程序对海量数据进行自动.高速地处理,然后把处理结果输出的现代化智能电子设备. 2.世界上第一台计算机是1946年诞生在美国宾州大学. 3.冯·诺依曼体系结构:1946年数学家冯·诺依曼于提出计算机硬件系统由运算器.控制器.存储器.输入设备.输出设备.摩根定律:当价格不变时,集成电路上可容纳的元器件的数目,约每隔18-24个月便会增加一倍,性能也将提升一倍.现在计算机技术进本很难遵

JAVA 初识类加载机制 第13节

JAVA 初识类加载机制 第13节 从这章开始,我们就进入虚拟机类加载机制的学习了.那么什么是类加载呢?当我们写完一个Java类的时候,并不是直接就可以运行的,它还要编译成.class文件,再由虚拟机解释给当前的操作系统去执行.这些过程都是我们看不见的,我们能看见的也就是一个.class文件.既然虚拟机要解释这些.class文件给当前的操作系统听,那么他怎么获得这些.class文件呢?虚拟机获得这些.class文件的过程就是类加载了. 所以,总结来说就是:虚拟机将.class文件从磁盘或者其他地

初识React

原文地址:北云软件-初识React 专注于UI 在MVC分层设计模式中,react常被拿来实现视图层(V).React不依赖于技术栈的其他部分,因此可以方便的在现有项目中尝试用它来实现一个小特性. 虚拟DOM React从DOM中抽象出来,给出一种更简洁的编程模型,且性能表现更好.能够通过NodeJS实现服务端渲染,通过React Native开发原生app. 数据流React实现单向.响应式数据流,减少boilerplate且比传统数据绑定更容易理解. 简洁的组件React的组件都实现了一个r

泛型的几种类型以及初识webform

今天学习的可以分为两类吧,但是学习的都是比较抽象的,不太容易掌握吧.首先我们大部分时间学习了泛型,泛型的委托,泛型接口以及枚举器,迭代器,扩展方法:最后简单的认识了webform,实现了一个简单的功能. 一.泛型 定义:泛型(generic)可以软糖多个类型共享一组代码,泛型允许我们声明类型参数化.可以用不同的类型进行实例化,说白了,就是可以用类型占位符,创建具体类型致命的真实概念.C#中提供了五种泛型,类,结构,接口,委托和方法.下面举例说明可能更容易理解, class MyStack<T>

最新计算机技术与管理科学应用专家——初识ERB

ERB管理系统:英文全称Enterprise Resource and Behavior,英文简称:ERB,中文名全称:企业资源与行为管理系统.ERB是由理文企业管理顾问有限公司首席管理师,现任商翼ERB企业管理系统项目总监吴志华先生,于2010年9月首先提出的.ERB不再单以供应链管理作为系统应用的基础,而是以企业行为与企业资源规划的最佳结合作为系统应用设计的核心基础,强调企业行为的规划.执行.监督与追溯,强调企业管理水平与员工素养的持续提升:提供企业行为与企业资源管理最佳结合的整体应用解决方

[OpenGL]环境搭建以及OpenGL初识

想往游戏行业发展的话,经常被提及到的就是OpenGL和DirectX,这两者听起来感觉是一门挺高深的技术,今天我也开始摸索学习OpenGL,那么OpenGL到底是什么?它和DirectX有什么区别和联系? OpenGL初识 OpenGL只是一套图形函数库 DirectX包含图形.声音.输入.网络等模块. 但就图形而论,DirectX的图形库性能不如OpenGL,OpenGL稳定,可以跨平台使用,DirectX只支持Windows平台,所以OpenGL还是有它的优势!OpenGL ES是OpenG

初识git

初识git 1 安装git 最早Git是在Linux上开发的,很长一段时间内,Git也只能在Linux和Unix系统上跑.不过,慢慢地有人把它移植到了Windows上.现在,Git可以在Linux.Unix.Mac和Windows这几大平台上正常运行了. 要使用Git,第一步当然是安装Git了.根据你当前使用的平台来阅读下面的文字: 1.1 在Linux上安装Git 首先,你可以试着输入git,看看系统有没有安装Git: ``` $ git The program 'git' is curren

初识linux文件管理

初识linux文件管理 1.文件系统与目录结构 文件系统从根目录 下开始,用"/". 以. 开头的文件为隐藏文件,路径分隔用/表示.文件系统的层级结构是LSB(linux standard base),遵循文件系统层级标准(FHS ) 文件命名规则:   文件名最长255个字节,包括路径名在内共4095个字节 蓝色–> 目录 绿色–> 可执行文件 红色–> 压缩文件 浅蓝色–> 链接文件 灰色–> 除了斜杠和NUL, 所有字符都有效,但不推荐使用特殊字符,