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