Go并发可视化解释 – select语句

2023-09-15 09:06:09

上周,我发布了一篇关于如何直观解释Golang中通道(Channel)的文章。如果你对通道仍然感到困惑,请先查看那篇文章。

Go并发可视化解释 — Channel

作为一个快速复习:Partier、Candier和Stringer经营着一家咖啡店。Partier负责接受顾客的订单,然后将这些订单传递给厨房,Candier和Stringer制作咖啡。

4a8b8c43a8b79926b670c3d1e8796628.png

Gophers' Cafe(Gopher咖啡馆)

在本文中,我将直观解释select语句,这是在Go应用程序中处理并发的另一个强大工具。Gophers和他们的虚构咖啡馆仍然是我的伙伴,但这次,让我们聚焦在Partier和点单部分。

情景

Gopher的Cafe意识到越来越多的顾客希望通过外卖应用程序在线订购咖啡。因此,除了店内点餐外,他们还选择了一个外卖应用程序。Partier会监视来自两个通道的订单,并通过另一个名为queue的通道将这些订单转发给Candier和Stringer。

select {
case order := <-appOrders:
    queue <- order
case order := <-inShopOrders:
    queue <- order
}

当这两个通道中的任何一个有订单时,Partier会获取订单并将其转发到queue通道。

fe6d479e742783133996ee53b4a09910.png 69b1d1c2bc704632ec8aa92d99d6ab50.png

如果这两个通道都有订单,将会选择其中一个。在实际的咖啡店中,来自inShopOrders的订单可能会被优先处理。但是,在Go应用程序中,我们无法保证哪个订单会被选择。还要注意,select语句的执行只会选择一个订单,Partier不会一次选择两个订单。但是,在许多应用程序中,select语句通常嵌套在for循环中,以便在前一个迭代中剩下的订单有机会在下一个迭代中被选择。

for {
    select {
    case order := <-appOrders:
        queue <- order
    case order := <-inShopOrders:
        queue <- order
    }
}

但是,如果这两个通道都有订单,它们将再次进行公平竞争。

5bcb1c847f1f6cec1d336f9b5758b175.png

默认情况(Default)

在非高峰时段,订单不多,Partier花费大量时间在等待上。他认为,他可以通过做其他事情来更有效地利用时间,例如清理桌子。这可以通过default来实现。

for {
    select {
    case order := <-appOrders:
        log.Println("There is an order coming from appOrders channel")
        queue <- order
    case order := <-inShopOrders:
        log.Println("There is an order coming from inShopOrders channel")
        queue <- order
    default:
        log.Println("There is no order on both channels, I will do cleaning instead")
        doCleaning()
    }
}

time.After()

time.After(duration)通常与select一起使用,以防止永久等待。与default不同,time.After(duration)会创建一个普通的<-chan Time,等待duration时间的流逝,然后将当前时间发送到返回的通道上。这个通道在select语句中与其他通道平等对待。正如你所看到的,select语句中的通道可以是不同类型的。

shouldClose := false
closeHourCh := time.After(8 * time.Hour)


for !shouldClose {
    select {
    case order := <-appOrders:
        log.Println("There is an order coming from appOrders channel")
        queue <- order
    case order := <-inShopOrders:
        log.Println("There is an order coming from inShopOrders channel")
        queue <- order
    case now := <-closeHourCh:
        log.Printf("It is %v now, the shop is closing\n", now)
        shouldClose = true
    default:
        log.Println("There is no order on both channels, I will go cleaning instead")
        doCleaning()
    }
}


log.Println("Shop is closed, I'm going home now. Bye!")

当处理远程API调用时,这种技术非常常见,因为我们无法保证远程服务器何时返回或是否返回。借助于context,通常不需要这样做。

responseChannel := make(chan interface{})
timer := time.NewTimer(timeout)


select {
case resp := <-
更多推荐

Android Fragment动画实现

在Android中,你可以使用FragmentTransaction来实现Fragment的动画效果。这允许你在添加、替换或移除Fragment时应用动画,从而改善用户体验。下面是如何实现Fragment动画的基本步骤:1.创建两个Fragment:首先,创建两个Fragment,例如FragmentA和Fragmen

TS同时打包和监视所有ts文件或只指定ts文件

当我们项目中ts文件较多时,我们如何直接打包所有ts文件为js文件?而不是使用tsc文件名一个一个去打包文件一、配置tsconfig.json文件创建一个tsconfig.json文件,该文件中不需要配置任何信息二、控制台输入打包命令在控制台输入如下代码:tsc三、对所有ts文件进行监听但是我们并没有对文件进行监听,修

Linux各种命令-查询篇

目录查看文件内容查看存储空间查看python安装目录查Ubuntu版本查看所有文件(含隐藏文件)查IP查看内存使用情况查看GPU使用情况查看CPU使用情况​​​​​​​查看文件内容cat[选项][文件...]-n:显示行号。-b:显示非空行号。-s:合并空白行。-E:在每行结尾添加$符号。-T:将制表符显示为^I。-v

交换机端口镜像详解

交换机端口镜像是一种网络监控技术,它允许将一个或多个交换机端口的网络流量复制并重定向到另一个端口上,以便进行流量监测、分析和记录。通过端口镜像,管理员可以实时查看特定端口上的流量,以进行网络故障排查、安全审计和性能优化。以下是关于交换机端口镜像的详细介绍:工作原理:交换机端口镜像通过在交换机的配置中指定源端口和目标端口

pycharm 中package, directory, sources root, resources root的区别

【遇到的问题】导入yolov5中有utils文件,自己的代码中也有utils文件,使得yolov5中的这部分引用出错了。【解决方案】单独建立detection文件夹,把检测相关的都放在这里,yolov5是github上拉取的源码,发现yolov5中fromutilsimport...有下划线,且会认为是edgeserv

多输入多输出 | MATLAB实现PSO-LSSVM粒子群优化最小二乘支持向量机多输入多输出

多输入多输出|MATLAB实现PSO-LSSVM粒子群优化最小二乘支持向量机多输入多输出目录多输入多输出|MATLAB实现PSO-LSSVM粒子群优化最小二乘支持向量机多输入多输出预测效果基本介绍程序设计往期精彩参考资料预测效果基本介绍MATLAB实现PSO-LSSVM粒子群优化最小二乘支持向量机多输入多输出1.dat

【码银送书第七期】七本考研书籍

八九月的朋友圈刮起了一股晒通知书潮,频频有大佬晒出“研究生入学通知书”,看着让人既羡慕又焦虑。果然应了那句老话——比你优秀的人,还比你努力。心里痒痒,想考研的技术人儿~别再犹豫了。小编咨询了一大波上岸的大佬,这份备考书单给大家参考。专业课(此处特指408,全称计算机专业基础综合)知识点超级多,题目灵活,数据结构、计算机

考研408 | 【计算机组成原理】 数据的表示和运算

进位计数制十进制计数法:推广:r进制计数法任意进制-->十进制:二进制<-->八进制、十六进制:各种进制的常见书写方式:十进制-->任意进制:十进制-->二进制(拼凑法):真值和机器数:总结:BCD码总结:无符号整数的表示和运算无符号整数在计算机中的应用:无符号整数的表示:无符号整数的加法运算:无符号整数的减法运算:总

uniapp运行到IOS真机提示 错误:请查看是否设备未加入到证书列表或者确认证书类型是否匹配

参考文章:请查看是否设备未加入到证书列表或者确认证书类型是否匹配ios开发描述文件必须绑定调试设备,只有授权的设备才可以直接安装基座,所以在申请开发描述文件之前,先添加调试的IOS设备。前往网站https://developer.apple.com,在Devices中,添加手机设备UUID第一步:登录第二步:检查设备列

VHOST-SCSI代码分析(1)VHOST SCSI设备模拟

VHOSTSCSI设备的模拟是由QEMU和HOST共同实现的,QEMU模拟VHOSTSCSI设备配置空间等,而对于虚拟机通知HOST和HOST通知虚拟机机制由HOST内核实现。在QEMU中VHOSTSCSI设备继承关系如下:其它设备以及对应class_init函数和realize具现化实现与VIRTIO-SCSI一致,

Learn Prompt-为什么用 ChatGPT API?

引用人工智能先驱吴恩达先生说过的话:“一个系统需要的远不止一个提示(prompt)或者一个对LLM(大性语言模型)的调用。”API的优点:集成更深:通过API,您可以将ChatGPT集成到自己的系统和工作流中,实现更深层次的定制和控制。个性化的响应:您可以根据特定需求和场景调整模型的响应,例如,通过改变温度(tempe

热文推荐