代码演示:

package main

import (
"fmt"
"math/rand"
"sync/atomic"
"time"
) type read0p struct {
key int
resp chan int
} type write0p struct {
key int
val int
resp chan bool
} func main() {
var read0ps uint64 = 0
var write0ps uint64 = 0
reads := make(chan *read0p)
writes := make(chan *write0p) go func() {
var state = make(map[int]int)
for {
select {
case read := <-reads:
read.resp <- state[read.key]
case write := <-writes:
state[write.key] = write.val
write.resp <- true
}
}
}() for r := 0; r < 100; r++ {
go func() {
for {
read := &read0p{
key: rand.Intn(5),
resp: make(chan int)}
reads <- read
<-read.resp
atomic.AddUint64(&read0ps, 1)
time.Sleep(time.Millisecond)
}
}()
}
for w := 0; w < 10; w++ {
go func() {
for {
write := &write0p{
key: rand.Intn(5),
val: rand.Intn(100),
resp: make(chan bool)}
writes <- write
<-write.resp
atomic.AddUint64(&write0ps, 1)
time.Sleep(time.Millisecond)
}
}()
}
time.Sleep(time.Second)
read0psFinal := atomic.LoadUint64(&read0ps)
fmt.Println("read0ps:", read0psFinal)
write0psFinal := atomic.LoadUint64(&write0ps)
fmt.Println("write0ps:", write0psFinal)
}

  

代码运行结果:

read0ps: 77702
write0ps: 7770

  

代码解读:

  • 本例子中的代码思路,和上一个例子中的代码思路大致相同,只是用协程通道来实现的
  • 在本例中,我们对state这个map进行读写操作,但是为了安全性和唯一性,我们让某一个协程单独拥有state这个map
  • 当某个协程想要对state进行操作的话,就发送请求到拥有state的这个协程中,然后再接收返回的结果
  • 本例中,有两个重要通道,分别是读reads和写writes,拥有state这个map的协程会监听这两个通道
  • 然后两个读read0ps和写write0ps的结构体中,又分别单独有一个通道用来存储结果
  • 当协程A想进行读操作时候,它会带着结构体resp这个通道,进入到读通道reads去,拥有state这个协程的通道从读通道reads中响应请求,然后把数据存入resp通道去,然后协程A再从resp通道中拿回结果
  • 同理协程B想进行写操作,也是如此

038_go语言中的状态协程的更多相关文章

  1. go语言从例子开始之Example37.Go 状态协程

    在前面的例子中,我们用互斥锁进行了明确的锁定来让共享的state 跨多个 Go 协程同步访问.另一个选择是使用内置的 Go协程和通道的的同步特性来达到同样的效果.这个基于通道的方法和 Go 通过通信以 ...

  2. 浅谈Go语言的Goroutine和协程

    0x00.前言 前面写了一篇初识Go语言和大家一起学习了Go语言的巨大潜力.语言简史.杀手锏特性等,感兴趣的读者可以回顾一下. 今天来学习Go语言的Goroutine机制,这也可能是Go语言最为吸引人 ...

  3. Android中的Coroutine协程原理详解

    前言 协程是一个并发方案.也是一种思想. 传统意义上的协程是单线程的,面对io密集型任务他的内存消耗更少,进而效率高.但是面对计算密集型的任务不如多线程并行运算效率高. 不同的语言对于协程都有不同的实 ...

  4. 转:一个C语言实现的类似协程库(StateThreads)

    http://blog.csdn.net/win_lin/article/details/8242653 译文在后面. State Threads for Internet Applications ...

  5. yield学习续:yield return迭代块在Unity3D中的应用——协程

    必读好文推荐: Unity协程(Coroutine)原理深入剖析 Unity协程(Coroutine)原理深入剖析再续 上面的文章说得太透彻,所以这里就记一下自己的学习笔记了. 首先要说明的是,协程并 ...

  6. Unity中巧用协程和游戏对象的生命周期处理游戏重启的问题

    主要用到协程(Coroutines)和游戏对象的生命周期(GameObject Lifecycle)基础知识,巧妙解决了游戏重启的问题. 关于协程,这里有篇文章我觉得写的非常好,理解起来也很容易.推荐 ...

  7. python中线程 进程 协程

    多线程:#线程的并发是利用cpu上下文的切换(是并发,不是并行)#多线程执行的顺序是无序的#多线程共享全局变量#线程是继承在进程里的,没有进程就没有线程#GIL全局解释器锁#只要在进行耗时的IO操作的 ...

  8. python编程中的并发------协程gevent模块

    任务例子:喝水.吃饭动作需要耗时1S 单任务:(耗时20s) for i in range(10): print('a正在喝水') time.sleep(1) print('a正在吃饭') time. ...

  9. Python中进程线程协程小结

    进程与线程的概念 进程 程序仅仅只是一堆代码而已,而进程指的是程序的运行过程.需要强调的是:同一个程序执行两次,那也是两个进程. 进程:资源管理单位(容器). 线程:最小执行单位,管理线程的是进程. ...

随机推荐

  1. numpy基础用法学习

    numpy get started 导入numpy库,并查看numpy版本 import numpy as np np.__version__ '1.14.0' 一.创建ndarray 1. 使用np ...

  2. 07-Python面对对象初级

    一.简介 面对过程编程: 根据操作数据的函数或语句块来设计程序. 面对对象编程:把一些函数,数据,方法和功能结合起来,用“对象”包裹组织程序的一种方法. 类和对象是面向对象编程的两个主要方面.类创建一 ...

  3. 使用SQL语句进行特定值排序

    使用SQL语句进行查询时,对数据进行排序,排序要求为排序的一个字段中特定值为顶部呈现: select * from TableName order by case TableFieldName whe ...

  4. 【翻译】.NET 5 Preview7发布

    今天,发布了.NET 5.0 Preview7.这是倒数第二个预览版本(在转移到RC之前).此时,大多数功能应该已经非常接近完成了.Single file和ARM64 intrinsics是两个花费了 ...

  5. 工程能力UP | LightGBM的调参干货教程与并行优化

    这是个人在竞赛中对LGB模型进行调参的详细过程记录,主要包含下面六个步骤: 大学习率,确定估计器参数n_estimators/num_iterations/num_round/num_boost_ro ...

  6. JS获取格式为YYYY-MM-DD的当前日期

    JS获取格式为YYYY-MM-DD的当前日期 var date = new Date();  var mon = date.getMonth() + 1; var day = date.getDate ...

  7. 面试题三十:包含min函数的栈

    定义一个栈的数据结构,请实现一个每次都能找到栈中的最小元素,要求时间复杂度O(1).意思就是说每次进栈出栈后,min函数总能在时间1的前提下找到.方法一:由于每次循序遍历栈的话时间复杂度为n,所以要想 ...

  8. List<Activity> lists的关闭finish()

    public class App extends Application { private static List<Activity> lists = new ArrayList< ...

  9. Python 写入excel时的字体格式设置

    转自:https://blog.csdn.net/kuangzhi9124/article/details/81940919 下面代码设置了单元格的字体.位置居中.框线,可以将格式调成自己需要的 im ...

  10. Mac Sourcetree克隆项目提示无效的url

    之前用SoucreTree拉去过另一个账号的git项目,今天创建了一个新的码云账号,克隆里面的项目是一直报错误 > 错误如下: > 原因以及解决方案: