协程goroutine
 
     不由OS调度,而是用户层自行释放CPU,从而在执行体之间切换。Go在底层进行协助实现
     涉及系统调用的地方由Go标准库协助释放CPU
     总之,不通过OS进行切换,自行切换,系统运行开支大大降低
 
 
通道channel
 
并发编程的关键在于执行体之间的通信,go通过通过channel进行通信
channel可以认为类似其他OS体系中的消息队列,只不过在go中原生支持,因而易用
 
消息队列有哪些值得关注的地方?常见问题包括创建、关闭或删除、阻塞、超时、优先级等,golang中也不例外。罗列如下:
     可否探测队列是满或空?或者说是否可以不阻塞地尝试读写?
     读阻塞和写阻塞时关闭会怎样?
     关闭后未读取的消息会被抛弃?
     往关闭的channel发送数据或读取数据会怎样?
     怎样探测channel的关闭?
     两个地方读或写阻塞同一个channel,有没有优先级?
     是否可以设定阻塞的超时时间?
     阻塞时怎样可以被弹出来?比如某些信号?
事实上,知道存在这些问题并进行分门别类是重要的,但知道这些问题的答案却不紧要,因为一般不会太过古怪,使用时临时试验一下即可。
 
已知的部分答案:
     好像不能不阻塞地尝试读写
     关闭会导致退出阻塞(似乎是一个不错的特性)
     可以探测关闭
     channel本身不能设定超时
了解这些似乎已经足够。
 
 
与众不同的地方值得我们重点留意,包括:
     除基本读写方式外,还有哪些特别的读写方式?在阻塞、关闭、超时方面又有什么不同?发现了select、range两个关键字
     推荐的多通道读
     推荐的同步方法
     推荐的超时方法
 
 
 
select
 
select可以实现无阻塞的多通道尝试读写,以及阻塞超时
     
var c, c1, c2, c3 chan int
var i1, i2 int
 
select {
     case i1 = <-c1: //如果能走通任何case则随机走一个
        print( "received ", i1, " from c1\n" )
     case c2 <- i2:
        print( "sent ", i2, " to c2\n" )
     case i3, ok := (<-c3):
        if ok {
                print( "received ", i3, " from c3\n" )
        } else {
                print( "c3 is closed\n")
        }
     default: // 如果case都阻塞,则走default,如果无default,则阻塞在case
        // default中可以不读写任何通道,那么只要default提供不阻塞的出路,就相当于实现了对case的无阻塞尝试读写
        print( "no communication\n")
}
 
实现阻塞超时的方法是,只要不给default出路,而在case中实现一个超时
 
timeout := make (chan bool, 1)
go func () {
    time.Sleep(1e9) // 这是等待1秒钟
    timeout <- true
}()
 
// 用timeout这个通道作为阻塞超时的出路
select {
  case <-ch:
  // 处理从ch中读到的数据
  case <-timeout:
  // 如果case都阻塞了,那么1秒钟后会从这里找到出路
 
 
range
 
range可以在for循环中读取channel
Go文档的翻译文是:对于信道,其迭代值产生为在该信道上发送的连续值,直到该信道被关闭。若该信道为 nil,则range表达式将永远阻塞
经过试验,range会阻塞,并且可以通过关闭channel来解除阻塞。
 
package main
 
import (
       "fmt"
)
 
func main() {
      ch := makechan int )
 
       go func () {
             for i := 0; i < 10; i++ {
                  ch <- i
            }
 
      }()
 
      
       for w := range ch {
            fmt.Println( "fmt print" , w)
             if w > 5 {
                   //break // 在这里break循环也可以
                   close(ch)
            }
      }
      fmt.Println( "after range or close ch!" )
}
 
 
Golang的并发编程还有其他细节,但以上是最主要脉络。

Golang协程与通道整理的更多相关文章

  1. [Golang]-5 协程、通道及其缓冲、同步、方向和选择器

    目录 协程 通道 通道缓冲 通道同步 通道方向 通道选择器 协程 Go 协程 在执行上来说是轻量级的线程. 代码演示 import ( "fmt" "time" ...

  2. 『GoLang』协程与通道

    作为一门 21 世纪的语言,Go 原生支持应用之间的通信(网络,客户端和服务端,分布式计算)和程序的并发.程序可以在不同的处理器和计算机上同时执行不同的代码段.Go 语言为构建并发程序的基本代码块是 ...

  3. Python与Golang协程异同

    背景知识 这里先给出一些常用的知识点简要说明,以便理解后面的文章内容. 进程的定义: 进程,是计算机中已运行程序的实体.程序本身只是指令.数据及其组织形式的描述,进程才是程序的真正运行实例. 线程的定 ...

  4. Golang协程实现流量统计系统(3)

    进程.线程.协程 - 进程:太重 - 线程:上下文切换开销太大 - 协程:轻量级的线程,简洁的并发模式 Golang协程:goroutine Hello world package main impo ...

  5. goroutine 分析 协程的调度和执行顺序 并发写 run in the same address space 内存地址 闭包 存在两种并发 确定性 非确定性的 Go 的协程和通道理所当然的支持确定性的并发方式(

    package main import ( "fmt" "runtime" "sync" ) const N = 26 func main( ...

  6. golang协程同步的几种方法

    目录 golang协程同步的几种方法 协程概念简要理解 为什么要做同步 协程的几种同步方法 Mutex channel WaitGroup golang协程同步的几种方法 本文简要介绍下go中协程的几 ...

  7. 面试必问:Golang高阶-Golang协程实现原理

    引言 实现并发编程有进程,线程,IO多路复用的方式.(并发和并行我们这里不区分,如果CPU是多核的,可能在多个核同时进行,我们叫并行,如果是单核,需要排队切换,我们叫并发) 进程和线程的区别 进程是计 ...

  8. golang协程——通道channel阻塞

    新的一年开始了,不管今天以前发生了什么,向前看,就够了. 说到channel,就一定要说一说线程了.任何实际项目,无论大小,并发是必然存在的.并发的存在,就涉及到线程通信.在当下的开发语言中,线程通讯 ...

  9. golang协程池设计

    Why Pool go自从出生就身带“高并发”的标签,其并发编程就是由groutine实现的,因其消耗资源低,性能高效,开发成本低的特性而被广泛应用到各种场景,例如服务端开发中使用的HTTP服务,在g ...

随机推荐

  1. Python选修课第二届Turtle绘图大赛~~画猫猫

    (a)20161401167 夏思敏 20161401179 段梦格 (b)代码执行视频链接 点击查看:Python使用turtle库画猫猫 (c)程序源码 import turtle turtle. ...

  2. JS实现——贪吃蛇

    把以下代码保存成Snake.html文件,使用Google或360浏览器打开 <!DOCTYPE HTML> <html> <head> <meta char ...

  3. C# 数组 之间转换

    List<string> strLen = new List<string>();            if (!string.IsNullOrEmpty(group_id) ...

  4. javascript基础 方法 函数 闭包 集合

    定义类 ,实例化对象类 ,调用 为类对象增加数据成员 --

  5. JS实现并集,交集和差集

    var set1 = new Set([1,2,3]);var set2 = new Set([2,3,4]); 并集let union = new Set([...set1, ...set2]); ...

  6. iOS-多线程(3)

    多线程之GCD(grand central dispatch)中心调度 为了简化多线程的操作,iOS为我们提供了GCD来实现编程. 使用GCD只要遵守两个步骤即可: 创建对列(串行队列,并行队列) 将 ...

  7. Linux 系统自动备份数据库及定时任务的设置

    首先想到数据库的自动备份,由于涉及业务原因需要在每天固定的时间去调用方法执行备份.如果不考虑业务要求,只考虑实现的话可以通过Linux系统提供的定时任务去完成备份操作. 本文讲的就是利用Linux系统 ...

  8. idea报错could not autowired .但是可以正常运行

    转 http://www.cnblogs.com/softidea/p/5763285.html 解决办法: File-->Project Setting-->Facets-->Sp ...

  9. OpenStack 通用设计思路

    API 前端服务 每个 OpenStack 组件可能包含若干子服务,其中必定有一个 API 服务负责接收客户请求. 以 Nova 为例,nova-api 作为 Nova 组件对外的唯一窗口,向客户暴露 ...

  10. SharePoint 2013 中的 URL 和标记

    SharePoint 2013 中的 URL 的类型                SharePoint 2013 分析 URL 字符串以基于指定的协议(例如,http:)确定 URL 的格式或确定正 ...