最近在学习了Go 语言 ,  正好学习到了 协程这一块 ,遇到了困惑的地方.这个是go语言官方文档 . 在我的理解当中是,协程只能在主线程释放时间片后才会经过系统调度来运行协程,其实正确的也确实是这样的,但是我遇到了协程强占主线程的一个问题,经过帮助,现在已经了解.废话不多说,先看代码

 1 package main
2
3 import (
4 "fmt"
5 "time"
6 )
7
8 func main() {
9 go say("world")
10 say("hello")
11 /*
12 fmt.Println("---------------1")
13
14 a := []int{7, 2, 8, -9, 4, 0}
15 fmt.Println("===", a[:len(a)/2])
16 c := make(chan int)
17 go sum(a[:len(a)/2], c)
18 go sum(a[len(a)/2:], c)
19 x, y := <-c, <-c // receive from c
20
21 fmt.Println(x, y, x+y)
22
23 fmt.Println("---------------2")
24
25 c2 := make(chan int, 2)
26 c2 <- 1
27 c2 <- 2
28 fmt.Println(<-c2)
29 fmt.Println(<-c2)
30
31 fmt.Println("---------------3")
32 c3 := make(chan int, 10)
33 go fibonacci(cap(c3), c3)
34 for i := range c3 {
35 fmt.Println(i)
36 }
37
38 fmt.Println("---------------4")
39 c4 := make(chan int)
40 quit := make(chan int)
41 go func() {
42 for i := 0; i < 10; i++ {
43 fmt.Println(<-c4)
44 }
45 quit <- 0
46 }()
47 fibonacci2(c4, quit)
48
49 fmt.Println("---------------5")
50 tick := time.Tick(100 * time.Millisecond)
51 boom := time.After(500 * time.Millisecond)
52 for {
53 select {
54 case <-tick:
55 fmt.Println("tick. ")
56 case <-boom:
57 fmt.Println("BOOM!")
58 return
59 default:
60 fmt.Println(" .")
61 time.Sleep(50 * time.Millisecond)
62 }
63 }*/
64 }
65
66 func say(s string) {
67 for i := 0; i < 5; i++ {
68 time.Sleep(100 * time.Millisecond)
69 fmt.Println(s)
70 }
71 }

先看两次代码运行结果

第一次:  (结合上面代码查看打印顺序)

第二次:(结合第一次查看打印顺序)

是不是发现了每次的打印顺序是不同的

这个就是协程强占执行

我们先来看下它的执行循序 , 主线程运行====>释放时间片====>协程运行==>释放时间片====>主线程运行

根据这段代码

1 say("hello")

我们知道,这个是属于主线程里面的,所以优先执行(注意实参是"hello")

然后看看 say 方法

1 func say(s string) {
2 for i := 0; i < 5; i++ {
3 time.Sleep(100 * time.Millisecond)
4 fmt.Println(s)
5 }
6 }

当执行到循环里面的

time.Sleep(100 * time.Millisecond)

会释放时间片,同时 暂停执行代码,系统调度到协程

go say("world")

也是同一个方法,同时也会执行

time.Sleep(100 * time.Millisecond)

释放时间片

于是再打印的时候就会出现强占执行

go 协程与主线程强占运行的更多相关文章

  1. 03_主线程联网问题&ANR&子线程不能修改UI

    如果不使用HAXM,恐怕网页源码查看器无法获取servlet的源码.初步猜测是安卓模拟器运行速度太慢了.如果CPU不支持VT-x的话,HAXM是安装不上的.所以可以先开启VT-x. 可以参考几篇文章h ...

  2. [C#参考]主线程和子线程之间的参数传递

    几个进程在大多数情况下要包含很多的子线程,那么他们之间免不了的要互相传递很多的参数,那么参数怎么传递的呢? 主线程向子线程传递参数的方法 第一种方法:Thraed类有一个带参数的委托类型的重载形式,这 ...

  3. C#主线程等待子线程运行结束

    佐左佑右 原文 C#主线程等待子线程运行结束 由于主程序中调用matlab的dll文件进行计算要用较长的时间,主界面会有很长时间的卡顿,造成的用户感受十分不好,因此我想在调用时,将调用放入子线程中,然 ...

  4. 通过使用Web Workers,Web应用程序可以在独立于主线程的后台线程中,运行一个脚本操作。这样做的好处是可以在独立线程中执行费时的处理任务,从而允许主线程(通常是UI线程)不会因此被阻塞/放慢。

    Web Workers API - Web API 接口参考 | MDNhttps://developer.mozilla.org/zh-CN/docs/Web/API/Web_Workers_API ...

  5. Java线程面试题:子线程先运行 2 次,然后主线程运行 4 次,如此反复运行 3 次

    package thread; /** * 需求:线程编程:子线程先运行 2 次,然后主线程运行 4 次,如此反复运行 3 次. * @author zhongfg * @date 2015-06-1 ...

  6. Java 并发编程中的 CountDownLatch 锁用于多个线程同时开始运行或主线程等待子线程结束

    Java 5 开始引入的 Concurrent 并发软件包里面的 CountDownLatch 其实可以把它看作一个计数器,只不过这个计数器的操作是原子操作,同时只能有一个线程去操作这个计数器,也就是 ...

  7. Java线程——线程习题(一)子线程执行10次后,主线程再运行5次,这样交替执行三遍

    题目:子线程执行10次后,主线程再运行5次,这样交替执行三遍 代码如下: package com.itheima.gan; /** * 子线程执行10次后,主线程再运行5次,这样交替执行三遍 * @a ...

  8. 四种方式实现子goroutine与主线程的同步

    如何实现子goroutine与主线程的同步 第一种方式: 这种方式很太死板,就不演示了. 第二种方式:使用 channel机制,每个 goroutine传一个 channel进去然后往里写数据,在再主 ...

  9. Java多线程--让主线程等待子线程执行完毕

    使用Java多线程编程时经常遇到主线程需要等待子线程执行完成以后才能继续执行,那么接下来介绍一种简单的方式使主线程等待. java.util.concurrent.CountDownLatch 使用c ...

随机推荐

  1. CodeForces 379F 树的直径 New Year Tree

    题意:每次操作新加两个叶子节点,每次操作完以后询问树的直径. 维护树的直径的两个端点U,V,每次计算一下新加进来的叶子节点到U,V两点的距离,如果有更长的就更新. 因为根据树的直径的求法,若出现新的直 ...

  2. [转] 彻底搞懂word-break、word-wrap、white-space

    white-space.word-break.word-wrap(overflow-wrap)估计是css里最基本又最让人迷惑的三个属性了,我也是用了n次都经常搞混,必须系统整理一下,今天我们就把这三 ...

  3. vim 查找替换命令

    http://vim.wikia.com/wiki/Search_and_replace

  4. luogu2698 [USACO12MAR]花盆Flowerpot

    单调队列+二分答案 #include <algorithm> #include <iostream> #include <cstring> #include < ...

  5. mysql update连表

    UPDATE price_air_item t1 LEFT JOIN order_item t2 ON t1.ORDER_ITEM_ID = t2.ORDER_ITEM_ID SET t1.BUYER ...

  6. Set容器——TreeSet及常用API

    TreeSet及常用Api ①   TreeSet为使用树来进行存储的Set接口提供了一个工具,对象按升序存储,访问和检索很快; ②   在存储了大量的需要进行快速检索的排序信息的情况下,TreeSe ...

  7. Graham扫描法 --求凸包

    前言: 首先,什么是凸包? 假设平面上有p0~p12共13个点,过某些点作一个多边形,使这个多边形能把所有点都“包”起来.当这个多边形是凸多边形的时候,我们就叫它“凸包”.如下图:  然后,什么是凸包 ...

  8. 九度oj 题目1358:陈博的平均主义

    题目描述: 在JOBDU团队里,陈博是最讲平均主义的人了,但并不是像梁山好汉那样能够做到有钱同花,有肉同吃,毕竟,他还是被家里的领导管着的……陈博的平均主义,就只能体现在他对数字的喜好了.陈博特别喜欢 ...

  9. Welcome-to-Swift-16自动引用计数(Automatic Reference Counting)

    Swift使用自动引用计数(ARC)来跟踪并管理应用使用的内存.大部分情况下,这意味着在Swift语言中,内存管理"仍然工作",不需要自己去考虑内存管理的事情.当实例不再被使用时, ...

  10. 【bzoj1449/bzoj2895】[JSOI2009]球队收益/球队预算 费用流

    题目描述 输入 输出 一个整数表示联盟里所有球队收益之和的最小值. 样例输入 3 3 1 0 2 1 1 1 10 1 0 1 3 3 1 2 2 3 3 1 样例输出 43 题解 费用流 由于存在一 ...