Concurrency 什么会导致go中的代码阻塞?

Concurrency 什么会导致go中的代码阻塞?,concurrency,go,Concurrency,Go,因为go是一种并发程序语言,使用通道(我几乎所有的代码都使用它)或其他东西来同步goroutine 我还知道go使用调度程序来调度goroutine,这意味着您应该在每个goroutine中调用调度程序(channel action,runtime.goSche或其他内容),并保证它会被执行 以上是我目前对go的所有限制,我使用它们来设计我的代码 但我也发现在我的代码中会出现代码阻塞。而且很难找到阻塞的原因(甚至使用GDB) 我错过什么了吗 还有什么可能导致阻塞 我应该注意哪些事情 [编辑]:好

因为go是一种并发程序语言,使用
通道(我几乎所有的代码都使用它)或其他东西来同步
goroutine

我还知道go使用调度程序来调度
goroutine
,这意味着您应该在每个goroutine中调用
调度程序(channel action,runtime.goSche或其他内容),并保证它会被执行

以上是我目前对
go
的所有限制,我使用它们来设计我的代码

但我也发现在我的代码中会出现代码阻塞。而且很难找到阻塞的原因(甚至使用GDB

我错过什么了吗

还有什么可能导致阻塞

我应该注意哪些事情

[编辑]:好的,因为我项目的代码有点大。我决定不显示标准
go
代码,只显示可能导致代码阻塞的部分的大致概念。以下是我的项目中文件传输模块的一些代码:

func(c *client)listenRead() {
    for {
        _ := websocket.JSON.Receive(c.ws, &package)
        switch package.Op {
        case fileUpld:
            c.fileMan.store <- package.Body
        case fileDownld:
            c.fileMan.downld <- package.Body
        case c.xxx:
            ...
        default:
            // bad package.
        }
    }
}
filemanager
可以在chan
fileUpld
获取从
客户端发送的数据时接收文件片段并存储到服务器。当它从客户端接收到
请求
时,它可以下载文件,并且它将生成一个
goroutine
来完成该工作,如下所示:

func(fm *fileManager) downldFile(fd) {
    f := getFile(fd)                     // get the file that client A write
    b := make([]byte, SeqLength)
    for {
        if convergence < window {
            f.Read(b)

            // wrap 'b' to package 'p', for send

            fm.server.send <- p   // send to client B
        } else if window < fileSize {
            runtime.Goshed()
        } else {
            // download done.
            fm.done <- xx
            return
        }
    }
}
我知道这会导致数据竞争,但它也保证
读取
不会读取
写入
尚未写入的内容。(BTW:我没有使用
频道
实现它的解决方案。)


当我尝试同时上传和下载时(我减慢客户端A以实现这一点),就会发生代码阻塞。但是,当我把<代码> GOMAXPROS/<代码>设置为2时,没有问题。

< P>你应该考虑一个垃圾收集器,它会暂停你的整个程序,因此被称为“停止世界”。在内存消耗大的大型应用程序上,GC可以“阻止世界”长达10秒,但这是最坏的情况。关于围棋中的GC,这里有一个很好的答案:

谢谢你的回答,这对我来说是新的东西。但事实上,有时它会超过10秒,我的应用程序并不是一个更大的应用程序,这可能不会导致大内存消耗。我想知道一些关于代码结构方面的考虑。如果您有一个代码示例来演示您正在讨论的问题,那么理解您的问题就会容易得多。如果你能让示例在play.golang.org上运行,那就更好了。@MatrixForg:我已经重新编辑并添加了代码示例。希望你更清楚。
func(fm *fileManager) downldFile(fd) {
    f := getFile(fd)                     // get the file that client A write
    b := make([]byte, SeqLength)
    for {
        if convergence < window {
            f.Read(b)

            // wrap 'b' to package 'p', for send

            fm.server.send <- p   // send to client B
        } else if window < fileSize {
            runtime.Goshed()
        } else {
            // download done.
            fm.done <- xx
            return
        }
    }
}
+-----------+---------------+--------------+
|############||||||||||||||||              |
+-----------+---------------+--------------+
            ^               ^              ^
            |               |              |
       convergence        window        filesize