美文网首页
Go 并发范式 超时

Go 并发范式 超时

作者: ShootHzj | 来源:发表于2021-06-27 10:40 被阅读0次

翻译自

https://blog.golang.org/concurrency-timeouts

Go并发范式:超时,继续执行

并发编程有自己的习惯用法。 超时是一个很好的例子。在商用软件开发时,所有操作都需要有超时。

虽然 Go 的channel不直接支持超时,但很容易实现。假设我们想从通道 ch 接收,但希望实现一秒钟超时。 我们可以创建一个信号channel并启动一个在通道上发送之前休眠的 goroutine

timeout := make(chan bool, 1)
go func() {
    time.Sleep(1 * time.Second)
    timeout <- true
}()

我们可以使用select语句从ch或者timeout中接收。如果过了1秒还没有数据返回,超时的case会被选中,尝试从ch读取的操作被放弃

select {
case <-ch:
    // a read from ch has occurred
case <-timeout:
    // the read from ch has timed out
}

timeout channel有1个buffer,允许超时 goroutine 发送到通道然后退出。 goroutine 不关心这个值是否被接收了。这意味着如果 ch 接收发生在超时之前,goroutine 不会永远挂起。timeout channel 最终会被gc释放。

(在这个例子中,我们使用 time.Sleep 来演示 goroutines 和通道的机制。在实际程序中,你应该使用 time.After来完成这个延迟发送)

让我们看看这种模式的另一种变体。在这个例子中,我们有一个程序可以同时从多个数据库的副本中读取数据。程序只需要一个结果,它应该接受最先返回的结果。

函数 Query 接受多个数据库连接和一个查询字符串。它并行查询每个数据库并返回它收到的第一个响应:

func Query(conns []Conn, query string) Result {
    ch := make(chan Result)
    for _, conn := range conns {
        go func(c Conn) {
            select {
            case ch <- c.DoQuery(query):
            default:
            }
        }(conn)
    }
    return <-ch
}

在这个例子中,闭包执行非阻塞发送,它通过在把send放在带有defaultselect中实现。 如果send不能立即完成,则将选择default情况。 非阻塞发送保证循环中启动的任何 goroutine 都不会挂起。

但是,这个例子中有一个问题,如果结果在主函数执行到11行接收的时候之前到达,发送都会失败,最终函数无法取得结果。

这个问题是所谓的竞争条件的教科书示例,修复非常简单。 我们只要保证channel有着缓冲通道(通过添加缓冲区长度作为 make 的第二个参数)来保证第一次发送有一个放置值的地方。 这确保发送总是成功,并且无论执行顺序如何,第一个值都会被获取。

这两个例子展示了 Go 可以简单地表达 goroutines 之间复杂的交互。

相关文章

  • Go 并发范式 超时

    翻译自 https://blog.golang.org/concurrency-timeouts[https://...

  • go语言进阶-并发

    title: go语言进阶-并发date: 2020-09-01 19:58:37 0. 前言 优雅的并发编程范式...

  • go并发编程范式

    1. 访问范围约束 通过限制访问约束,减少不必要的同步带来的性能损耗。例如,集中控制channel的写入,对外提供...

  • golang之channel用法[转]

    转自 Go Channel 高级实践 用法 超时控制 取最快的结果 限制最大并发数 for...range 优先 ...

  • Go 并发编程:通道常见应用范式

    通道经典应用 一、闭包实现通道访问限制 在Go的并发编程中,创建通道和开辟协程是非常方便且容易的,正因如此,有可能...

  • Go 并发编程:Goroutine常见应用范式

    一、多独立协程并发——worker分工模式 并发协程独立运行且互不通信,主协程等待处理独立子协程的结果 并发编程有...

  • Go语言并发

    Go语言并发 Go语言级别支持协程,叫做goroutine Go 语言从语言层面支持并发和并行的开发操作 Go并发...

  • Go基础语法(九)

    Go语言并发 Go 是并发式语言,而不是并行式语言。 并发是指立即处理多个任务的能力。 Go 编程语言原生支持并发...

  • go语言特点 --- 2022-06-03

    一:go语言特点: 静态类型,编译型开源语言2.脚本化语法,支持多种编程范式3.原生给力的并发编程注意:原生支持和...

  • Go并发模型:并发协程chan的优雅退出

    Go并发模型:并发协程chan的优雅退出 go chan的使用

网友评论

      本文标题:Go 并发范式 超时

      本文链接:https://www.haomeiwen.com/subject/hfxxultx.html