Go语句和通道类型是Go语言的并发编程理念的最终体现。与defer语句相同,go语句也可以携带一个表达式语句。Go语句的执行会很快结束,并不会对当前流程的进行造成阻塞或明显的延迟。一个简单的示例:

go fmt.Println("Go")

go语句仅由一个go关键字和一条表达式语句组成。同样的,go语句的执行与其携带的表达式语句的执行在时间上没有必然联系。这里能确定的仅仅是后者会在前者完成之后发生。在go语句被执行时,其携带的函数(也称为go函数)以及要传给它的若干参数会被封装成一个实体(即Goroutine),并被放入到相应的待运行队列中。Go语言的运行时系统会适时的从队列中取出待运行的Goroutine并执行相应的函数调用操作。注意,对传递给这里的函数的那些参数的求值会在go语句被执行时进行。
  正是由于go函数的执行时间的不确定性。所以Go提供了很多方法来协调它们的运行。其中最简单粗暴的方法就是time.Sleep函数:

package main

import {
"fmt"
} func main() {
go fmt.Println("Go!")
}

上面的代码运行时,不会有任何输出,因为还没等go语言运行时系统调用那个go函数执行主函数main就已经执行完毕了。函数main的执行完毕意味着整个程序的执行的结束。因此,这个go函数就不会执行。
  当我们在上述go语句的后面添加一条对time.Sleep函数的调用语句之后情况就不同了:

package main

import {
"fmt"
"time"
} func main() {
go fmt.Println("Go!")
time.Sleep(100 * time.Millisecond)
}

语句time.Sleep(100 * time.Millisecond)会把main函数的执行结束时间向后延迟100毫秒,这样go函数就会被调度执行了。
  另外比较优雅的做法是在main函数的最后调用runtime.Gosched函数:

package main

import {
"fmt"
"runtime"
} func main() {
go fmt.Println("Go")
runtime.Gosched()
}

runtime.Gosched函数的作用是让当前正在运行的Goroutine(这里是运行main函数的那个Goroutine)暂时“休息”一下,而让Go运行时系统转去运行其他的Goroutine(这里是与go fmt.Println("Go!"))对应并会封装fmt.Println("Go!")的那个Goroutine)。
  还有另外的方法可以满足上述需求。如果我们要控制更多的Goroutine的运行时机的话,下面的方法更好:

package main

import {
"fmt"
"sync"
} func main() {
var wg sync.WaitGroup
wg.Add(3)
go func () {
fmt.Println("Go!")
wg.Done()
}() go func() {
fmt.Println("Go!")
wg.Done()
}() go func() {
fmt.Println("Go!")
wg.Done()
}() wg.Wait()
}

sync.WaitGroup类型有三个方法可用--Add、Done和Wait。Add会使其所属值的一个内置整数得到相应增加,Done会使那个整数减1,而wait方法会使当前Goroutine阻塞直到那个整数为0。上例中,我们在main函数中启用了三个Goroutine来封装三个Go函数。每个匿名函数的最后都调用了wg.Done方法。并以此表达当前的go函数会立即执行结束的情况。当这三个go函数都调用过wg.Done函数之后,处于main函数最后的那条wg.Wait()语句就不会阻塞,main函数的执行将立即结束。

Golang 笔记 5 go语句的更多相关文章

  1. golang笔记1

    golang笔记1 go代码是用包来组织的,每个包有一个或多个go文件组成,这些go文件文件放在一个文件夹中 每个源文件开始都用一个package声明,指明本源文件属于哪个包 pakage声明后紧跟这 ...

  2. Golang笔记(一)简洁的语言风格

    Golang笔记(一)简洁的语言风格 概述 Golang继承了很多C语言的风格,寡人使用了十几年C语言,切换到Golang时上手很快,并且随着深入的使用,越来越喜欢这门语言.Golang最直观的感受是 ...

  3. Golang笔记(二)面向对象的设计

    Golang笔记(二)面向对象的设计 Golang本质还是面向过程的语言,但它实现了一些OOP的特性,包括抽象.封装.继承和多态. 抽象和封装 Golang和C语言一样以struct为数据结构核心,不 ...

  4. 【SQL Server学习笔记】Delete 语句、Output 子句、Merge语句

    原文:[SQL Server学习笔记]Delete 语句.Output 子句.Merge语句 DELETE语句 --建表 select * into distribution from sys.obj ...

  5. Golang 笔记 3 if、switch、for、select语句

    一.if语句 Go的流程控制主要包括条件分支.循环和并发.  if语句一般由if关键字.条件表达式和由花括号包裹的代码块组成.在Go中,代码块必须由花括号包裹.这里的条件表达式是结果类型为bool的表 ...

  6. Golang笔记整理--One day

    题外话: 很早就有整理学习笔记的想法,今天将想法付诸于行动,将Golang相关知识系统整理一遍,此分类为Golang学习笔记,最近开始学习这门语言的同学可以参考. 一 第一个Go程序: hello.g ...

  7. golang笔记——函数与方法

    如果你遇到没有函数体的函数声明,表示该函数不是以Go实现的. package math func Sin(x float64) float //implemented in assembly lang ...

  8. Golang 笔记 1 基础、基本数据类型

    一.Go语言基础 1. 基础 Go语言中的标识符必须以字母(Unicode字母,PHP/JS可以用中文作为变量名)下划线开头.大写字母跟小写字母是不同的:Hello和hello是两个不同的名字.  G ...

  9. golang笔记:unsupported driver -> Scan pair: <nil> -> *string

    golang里,操作mysql数据库,使用查询语句的时候,一般的写法 rows, err := db.Query("select name from table") if err ...

随机推荐

  1. vue-cli webpack2项目打包优化

    减小文件搜索范围 配置 resolve.modules Webpack的resolve.modules配置模块库(即 node_modules)所在的位置,在 js 里出现 import 'vue' ...

  2. Python之函数第三篇

    一.匿名函数 匿名函数是lambda定义的没有名字的具有一些小功能的函数 具体形式是 lambda x: X**2 # 求平方操作 lambda x: x>100 # 判断参数是否大于100 二 ...

  3. JS_高程4.变量,作用域和内存问题(1)

    1.基本类型和应用类型的值 ECMAScript变量可能包含两种不同数据类型的值: 基本类型值——简单的数据段.(5种基本的数据类型,按值访问,因为可以操作保存在变量中的实际的值.) 引用类型值——多 ...

  4. Vue(十七)模块化开发

    模块化开发   使用vue-cli创建项目   1. vue-router模块化   引入vue-router cnpm install vue-router -S 1.1 编辑main.js imp ...

  5. mvc中使用Pagination,对其进行再封装

    对其进行再次封装: (function($) { $["fn"]["easyPaging"] = function(o) { if (!o.pageSelect ...

  6. python部分面试- 测试维度

    2. 软件测试的维度 1. 正确性:功能 正确 2. 健壮性: 意外的输入,不会崩溃 3. 性能: 大压力, 依然能工作 4. 可靠性: 长时间,不会崩溃 5. 易用性: 目标客户,都易用 6. 安全 ...

  7. GMA Round 1 三视图

    传送门 三视图 该几何体如图所示,是一个边长为$2\sqrt{3}$的正四面体,高是$h=2\sqrt{2}$,内切球半径是$r=\frac{h}{4}=\frac{\sqrt{2}}{2}$,则体积 ...

  8. 替换空字符NULL(字符编码为0的字符)

    老R3(非Unicode系统),发现读取出来的数据中有编码为0的字符,存文件后发现串行,所以需要先替换 DATA: str TYPE string. *str = zacct_12-txt+47. s ...

  9. Exchange Online Mailbox Restoration

    User Account is already deleted in AD.User Mailbox is already deleted in Exchange. 1. Connect to Exc ...

  10. iOS获取当前城市

    1.倒入头文件 #import <CoreLocation/CoreLocation.h> 2.实现定位协议CLLocationManagerDelegate 3.定义定位属性 @prop ...