go - 理解 Go 中的死锁

标签 go deadlock

我从编程类(class)中给出的示例中摘录了以下摘录,我不确定为什么会发生死锁。

package main

import (
    "fmt"
)

var (
    Count      int = 0
    nFunctions int = 2
)

var sema = make(chan int)

func increment(ch chan int, nSteps int) {
    for i := 0; i < nSteps; i++ {
        <- sema  
        cnt := Count
        Count = cnt + 1
        ch <- 1
        sema <- 1
    }
    return
}

func main() {
    ch := make(chan int)
    sema <- 1
    go increment(ch, 1000)
    go increment(ch, 1000)

    for i := 0; i < nFunctions*1000; i++ {
        <-ch
    }

    fmt.Printf("Count = %d\n", Count)
}

奇怪的是,当我从 sema <- 1 更改语句时,不会发生死锁。到
go func () {
sema <- 1
}()

对此的任何解释都非常感谢。错误信息是:
fatal error :所有 goroutine 都处于休眠状态 - 死锁!

goroutine 1 [chan 发送]:
main.main()

最佳答案

channel 阻塞发送者和接收者。如果您发送某些东西,您将被阻止,直到收到为止。您可以进一步减少代码,您只需要一个 channel ,然后写入该 channel 。请注意,您也可以使用 buffered channel ,它允许写入到缓冲区长度而不会阻塞。但是,如果缓冲区已满,它仍然会阻塞。

关于go - 理解 Go 中的死锁,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59884275/

相关文章:

html - 如何将 html 表单中的日期和时间输入类型存储到 sqlite3 DB 中

go - 在Go中比较结构

java - 下面的死锁场景中编写的代码是什么样的?

c++ - 是否有 "single mutex deadlock"的术语(非递归互斥的死锁类型情况)?

multithreading - 锁定层次结构和读写器互斥体

go - Printf 错误。新的可能吗?

go - 在 GO 中将字符串转换为函数名称?

static - 如何在 Go 中拥有非共享的状态变量?

SQL Server 记录行访问最佳实践

java - 我该如何解决这个明显的 EhCache 死锁?