Gosched

暂停当前goroutine,使其他goroutine先行运算。只是暂停,不是挂起,当时间片轮转到该协程时,Gosched()后面的操作将自动恢复

未使用Gosched的代码
package main

import (
"fmt"
) func main() {
go output("goroutine 2") output("goroutine 1")
} func output(s string){
for i:=0;i<3;i++{
fmt.Println(s)
}
}
输出
goroutine 1
goroutine 1
goroutine 1

结论:还没等到子协程执行,主协程就已经执行完退出了,子协程将不再执行,所以打印的全部是主协程的数据。当然,实际上这个执行结果也是不确定的,只是大概率出现以上输出,因为主协程和子协程间并没有绝对的顺序关系

使用Gosched的代码
package main

import (
"fmt"
"runtime"
) func main() {
go output("goroutine 2") runtime.Gosched()
output("goroutine 1")
} func output(s string){
for i:=0;i<3;i++{
fmt.Println(s)
}
}
输出
goroutine 2
goroutine 2
goroutine 2
goroutine 1
goroutine 1
goroutine 1

结论:在打印goroutine 1之前,主协程调用了runtime.Gosched()方法,暂停了主协程。子协程获得了调度,从而先行打印了goroutine 2。主协程不是一定要等其他协程执行完才会继续执行,而是一定时间。如果这个时间内其他协程没有执行完,那么主协程将继续执行,例如以下例子

使用Gosched的代码,并故意延长子协程的执行时间,看主协程是否一直等待
package main

import (
"fmt"
"runtime"
"time"
) func main() {
go func() {
time.Sleep(5000)
output("goroutine 2")
}() runtime.Gosched()
output("goroutine 1")
} func output(s string) {
for i := 0; i < 3; i++ {
fmt.Println(s)
}
}
输出
goroutine 1
goroutine 1
goroutine 1

Goexit

立即终止当前协程,不会影响其它协程,且终止前会调用此协程声明的defer方法。由于Goexit不是panic,所以recover捕获的error会为nil

当main方法所在主协程调用Goexit时,Goexit不会return,所以主协程将继续等待子协程执行,当所有子协程执行完时,程序报错deadlock

package main

import (
"fmt"
"runtime"
"time"
) func main() {
go func(){
defer func(){
fmt.Println("defer func executed!")
fmt.Println("recovered error == ",recover())
}() for i:=0;i<3;i++{
if i==1{
runtime.Goexit()
} fmt.Println(i)
}
}() time.Sleep(2*time.Second)
}
输出
0
defer func executed!
recovered error == <nil>

GOMAXPROCS(n int) int

设置可同时执行的逻辑Cpu数量,默认和硬件的线程数一致而不是核心数,可以通过调用GOMAXPROCS(-1)来获取当前逻辑Cpu数

最好在main函数之前设置它,GOMAXPROCS同时也是go的环境变量之一

​ 当n<1:非法数字,方法不作修改

​ 当n==1:单核心,多协程并发执行,并发只是看起来是同时执行的,实际上是同一时刻只有一个协程在跑,只是由于cpu的任务调度算法,让多个协程在效果上同时执行

​ 当n>1:多核心,多协程并行执行,并行一定是并发,不同的核心同时地跑不同的协程

想要了解更多有关并发(Concurrency)和并行(Parallel)的区别,可以看看大神Rob Pike的视频Concurrency Is Not Parallelism,里面有很详细的讲解

作者:胡金生

出处:www.aprilboy.com

版权所有,欢迎保留原文链接进行转载:)

浅析runtime包中的三个方法Gosched、Goexit、GOMAXPROCS的更多相关文章

  1. Java网络编程和NIO详解4:浅析NIO包中的Buffer、Channel 和 Selector

    Java网络编程与NIO详解4:浅析NIO包中的Buffer.Channel 和 Selector 转自https://www.javadoop.com/post/nio-and-aio 本系列文章首 ...

  2. 创建如下三个类:(People类中的三个方法分别输出一些信息,ChinaPeople 和AmericanPeople类重写父类的三个方法)。

    创建如下三个类:(People类中的三个方法分别输出一些信息,ChinaPeople 和AmericanPeople类重写父类的三个方法). ackage com.chuoji.text01; pub ...

  3. Spring自动扫描无法扫描jar包中bean的解决方法(转)

    转载自:http://www.jb51.net/article/116357.htm 在日常开发中往往会对公共的模块打包发布,然后调用公共包的内容.然而,最近对公司的公共模块进行整理发布后.sprin ...

  4. Web项目替换jar包中的文件的方法

    经常遇到这样的问题,需要修改jar包中的方法.应该如何做? 1.有些很人性化的框架jar包,比如SpringSecurity,可以修改配置文件指定一个新建的类,让类实现Jar包中的对应的接口就好了. ...

  5. Java网络编程与NIO详解4:浅析NIO包中的Buffer、Channel 和 Selector

    微信公众号[黄小斜]作者是蚂蚁金服 JAVA 工程师,目前在蚂蚁财富负责后端开发工作,专注于 JAVA 后端技术栈,同时也懂点投资理财,坚持学习和写作,用大厂程序员的视角解读技术与互联网,我的世界里不 ...

  6. ASP.NET MVC 中将数据从View传递到控制器中的三种方法(表单数据绑定)

    http://www.cnblogs.com/zyqgold/archive/2010/11/22/1884779.html 在ASP.NET MVC框架中,将视图中的数据传递到控制器中,主要通过发送 ...

  7. Java中 util 包 Calendar类制作万年历(不用自己写方法,直接用Java写好的包中的类的方法)

    代码前需要了解的关于Calendar类的内容:      1.在util包中,首先要知道Calendar 提供了一个类方法 getInstance,以获得此类型的一个通用的对象.Calendar 的 ...

  8. go语言之进阶篇runtime包中 Gosched Goexit GOMAXPROCS的使用

    一.runtime包 1.Gosched的使用 runtime.Gosched() 用于让出CPU时间片,让出当前goroutine的执行权限,调度器安排其他等待的任务运行,并在下次某个时候从该位置恢 ...

  9. wireshark分析包中关于三次握手和四次终止标识

    转自: http://hi.baidu.com/hepeng597/item/5ba27e0b98bc8de3ff240de0 三次握手Three-way Handshake 一个虚拟连接的建立是通过 ...

随机推荐

  1. springBean生命周期----来自spring实战总结

    1.Spring对bean进行实例化 2.Spring将值和bean的引用注入到bean对应的属性中(比如说注入到被依赖的bean的方法中或属性里) 3.如果bean实现了BeanNameAware接 ...

  2. Python学习2——Python单行注释、整段注释使用方法

    Python中的注释有多种,有单行注释,多行注释,批量注释,中文注释也是常用的. python注释也有自己的规范,在文章中会介绍到. 注释可以起到一个备注的作用,团队合作的时候,个人编写的代码经常会被 ...

  3. SpringMvc返回JSON出现"$.result.currentLevel"

    "$.result.currentLevel" 问题描述 使用SpringMvc返回一个json数据的时候,会在产生的结果中出现如下的问题:"$.result.curre ...

  4. C#2.0新增功能06 协变和逆变

    连载目录    [已更新最新开发文章,点击查看详细] 在 C# 中,协变和逆变能够实现数组类型.委托类型和泛型类型参数的隐式引用转换. 协变保留分配兼容性,逆变则与之相反. 以下代码演示分配兼容性.协 ...

  5. MYSQL主从复制、主主复制、双主多从配置

    一.如何配置MYSQL的主从复制? 1. 两台数据库服务器,IP分别为 192.168.216.128 和 192.168.216.129,在服务器上装MYSQL(我的配置版本为5.5.56) 2. ...

  6. 任何类型的数据都向String转型

    String从其定义上发现首字母大写,所以此为一个类,属于引用数据类型,但是此类属于系统的类. (1)String像普通变量一样直接通过复制的方式进行声明.字符串使用双引号括起来.两个字符串使用&qu ...

  7. CSS和html如何结合起来——选择符及优先级

       1.选择符     兼容性 统配选择符 *         元素选择符 body   类选择符 .class   id选择符 #id         包含原则符 p strong     (所有 ...

  8. ios下,微信小程序scrollview组件中的fixed元素抖得和帕金森病人一样

    问题现象 这个问题是最近在优化小程序代码时发现的. 在ios环境下,微信小程序的scrollview组件包裹着一个position:fixed的view. 当在scrollview组件上滑动时,这个v ...

  9. 【iOS】Assertion failure in -[MASViewConstraint install]

    刚遇到了这个问题,详细信息如下: Assertion failure 错误原因: 控件没有添加到视图就使用 mas_makeConstraints 了……应该先把控件添加到视图.

  10. Liunx C 编程之多线程与Socket

    多线程 pthread.h是linux特有的头文件,POSIX线程(POSIX threads),简称Pthreads,是线程的POSIX标准.该标准定义了创建和操纵线程的一整套API.在类Unix操 ...