go runtime.Gosched() 和 time.Sleep() 做协程切换

   网上看到个问题:

  

package main

import (
    "fmt"
    "time"
)

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

func main() {
    go say("world")
    say("hello")
}

只有使用time.sleep(100 * time.Millisecond) 时才会连续打出5个hello world

解释是 go 是非抢占的,只有出让cpu时,另外一个协程才会运行。如果没有time.sleep(100 * time.Millisecond)就只会打出5个hello出来。

还有另外一个协程切换的方式:

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")
    say("hello")
}

这个只是打出了5 个hello 4个world ----原因不明。

比对了下 Gosched() 和 Sleep() 两者运行的时候系统的情况:

package main

import (
//    "fmt"
    "runtime"
//    "time"
)

func say(){
    for i := 0; i < 10000000; i++{
//        time.Sleep(1 * time.Millisecond)
    runtime.Gosched()
//        fmt.Println(s)
    }
}

func main(){
    go say()
    say()
}

发现cpu使用率在使用Gosched() 时 比 Sleep() 要高,但是运行的时间比Sleep()的方式明显要短一些。---这里面切换的方式需要在网上找找有没有资料了.

相关:

http://stackoverflow.com/questions/15771232/why-is-time-sleep-required-to-run-certain-goroutines

时间: 2024-11-08 20:08:24

go runtime.Gosched() 和 time.Sleep() 做协程切换的相关文章

协程介绍前戏、协程切换手动、协程切换自动

一.协程简介.引子 ''' 协程:异步IO,队列,缓存 Nginx效率高就是用了异步IO 协程是一种用户态的轻量级线程.又称微线程,怎么理解呢?后面会说 CPU只认识线程,不会像线程一样吧上下文保存在CPU寄存器,协程是用户控制的. 协程能保留上一次调用时的状态,单线程下实现并发效果 协程的好处: 1.无需线程上下文切换的开销,用yield的时候,只是在函数之间来回切换 2.无需原子操作锁定及同步的开销,没有异步锁之类的东西,因为协程就是单线程 3.方便切换控制流,简化编程模型 4.高并发-高扩

游戏服务器之多进程架构通信 协程切换只是简单地改变执行函数栈,不涉及内核态与用户态转化,也涉及上下文切换,

游戏服务器之多进程架构通信 https://gameinstitute.qq.com/community/detail/124098 https://www.zhihu.com/question/23508968 游戏服务器与普通服务器有什么区别? 游戏开发中的TCP.UDP.HTTP.WebSocket四种网络通讯协议对比 https://gameinstitute.qq.com/community/detail/127562 https://www.jianshu.com/p/4eb37c1

greenlet 实现手动协程切换

from greenlet import greenlet def test1(): print('12') gr2.switch() #切换到gr2 print('34') gr2.switch() def test2(): print('56') gr1.switch() print('78') gr1 = greenlet(test1) #创建一个test1的协程gr2 = greenlet(test2) #创建一个test2的协程 gr1.switch() #手动切换到gr1 原文地址:

Gevent的socket协程安全性分析

一般讨论socket的并发安全性,都是指线程的安全性...而且绝大多数的情况下socket都不是线程安全的.. 当然一些框架可能会对socket进行一层封装,让其成为线程安全的...例如java的netty框架就是如此,将socket封装成channel,然后让channel封闭到一个线程中,那么这个channel的所有的读写都在它所在的线程中串行的进行,那么自然也就是线程安全的了..... 其实很早看Gevent的源码的时候,就已经看过这部分的东西了,当时就已经知道gevent的socket不

[NIO]从300万到700万——dawn的协程优化

dawn的协程库,使用的是kilim,不过已经远非kilim的原有代码,主要保留了协程的两个基本原语,再往上层,已经全部被替换了. 协程库,我学习过boost asio中的协程,也在我的机器上测试过单纯上下文切换的速度.这个速度在不同的机器之间没有可比性,因为彼此的cpu可能不同.但是在同一台机器上的不同库的对比,具有一定的参照性. 我记得,当时asio协程单线程情况下,协程切换的最高持续吞吐量大概是400万次每秒. 我当时是准备使用kilim,所以在同一时间也测试了kilim,我记得当时测试出

谈谈对协程的理解

什么是协程 协程是在线程之上由“用户”构建的并发单元,对OS来说无感知,协程的切换由用户自己管理和调度.(这里的用户是相较于内核而言的,一些通用库这里也理解为用户) C/C++怎么实现协程 作为一个C++后台开发,我知道像go, lua之类的语言在语言层面上提供了协程的api,但是我比较关心C++下要怎么实现这一点,下面的讨论都是从C/C++程序员的角度来看协程的问题的. boost和腾讯都推出了相关的库,语言层面没有提供这个东西.我近期阅读了微信开源的libco协程库,协程核心要解决几个问题:

魅族C++协程框架(Kiev)技术内幕

Kiev框架简介 kiev是魅族科技推送平台目前使用的Linux-C++后台开发框架.从2012年立项起,先后由多位魅族资深架构师.资深C++工程师倾力打造,到本文写就的时间为止,已经在推送平台这个千万用户级的大型分布式系统上经历了近5年的考验.如今Kiev在魅族推送平台中,每天为上百个服务完成数百亿次RPC调用. kiev作为一套完整的开发框架,是专为大型分布式系统后台打造的C++开发框架,由以下几个组件组成: RPC框架(TCP/UDP) FastCGI框架 redis客户端(基于hired

Python之路【第七篇续】:进程、线程、协程

Socket Server模块 SocketServer内部使用 IO多路复用 以及 "多线程" 和 "多进程" ,从而实现并发处理多个客户端请求的Socket服务端.即:每个客户端请求连接到服务器时,Socket服务端都会在服务器是创建一个"线程"或者"进 程" 专门负责处理当前客户端的所有请求. socket server 和 select & epoll 还是不太一样他的本质是:客户端第一次链接的时候,只要一进来

Python的线程&amp;进程&amp;协程[0] -&gt; 基本概念

基本概念 / Basic Concept 0 简介与动机 / Why Multi-Thread/Multi-Process/Coroutine 在多线程(multithreaded, MT)编程出现之前,计算机程序的执行是由单个步骤序列组成的,该序列在主机的CPU中按照同步顺序执行.即无论任务多少,是否包含子任务,都要按照顺序方式进行. 然而,假定子任务之间相互独立,没有因果关系,若能使这些独立的任务同时运行,则这种并行处理方式可以显著提高整个任务的性能,这便是多线程编程. 而对于Python而