Golang的通道无法消费或发布。

huangapple go评论73阅读模式
英文:

golang channel can't consume or publish

问题

在我的代码中,只有部分代码。我初始化了一个通道,该通道无法消费或发布。我不知道是什么原因导致这种情况发生。

//程序开始时初始化
var stopSvr chan bool
stopSvr = make(chan bool)
var stopSvrDone chan bool
stopSvrDone = make(chan bool)

//在某个地方使用,在一个goroutine中
select {
case <-stopSvr:
stopSvrDone <- true
fmt.Println("子服务器退出")
default:
//执行其工作
}

//在某个地方使用,在一个goroutine中
stopSvr <- true //在这里阻塞
<-stopSvrDone
fmt.Println("服务器退出")

//在这里做其他事情,但在"stopSvr<-true"处被阻塞,
//有什么条件会导致这种情况发生?

结论:
我不清楚通道的阻塞和解除阻塞。
我不清楚select{}表达式中的关键字"default"。
这就是为什么我的程序无法运行的原因。

感谢@jimt,我解决了这个问题。

英文:

In my code below,just part of the whole code.I init a channel, the channel can't consume or publish.I don't konw what make this happen.

//init at the beginning of program
var stopSvr chan bool
stopSvr=make(chan bool)
var stopSvrDone chan bool
stopSvrDone=make(chan bool)

//somewhere use,in a goroutine
select{
    case &lt;-stopSvr:
        stopSvrDone&lt;-true
        fmt.Println(&quot;son svr exit&quot;)
    default:
        //do its job
}

//somewhere use,in a goroutine
stopSvr &lt;- true //block here
&lt;-stopSvrDone
fmt.Println(&quot;svr exit&quot;)

//here to do other things,but it&#39;s blocked at &quot;stopSvr&lt;-true&quot;,
//what condition could make this happen?

conclusion:
channel's block and unblock,I didn't know clearly.
select{} expr keyword 'default',I didn't know clearly.
that's why my program didn't run.

thanks @jimt ,I finish the problem.

答案1

得分: 0

我不确定你想要实现什么。但是你的示例代码在select语句上肯定会阻塞。

select语句中的default情况用于在特定的读取或写入通道不成功时提供备用方案。这意味着在你的代码中,default情况总是会被执行。在select开始之前,通道中没有任何值被写入,因此case语句永远不会运行。

default情况中的代码永远不会成功并且会无限期地阻塞,因为通道中没有空间来存储值,也没有其他goroutine从中读取。

解决你当前问题的一个简单方法是:

stopSvr = make(chan bool, 1) // 使用1个缓冲槽来存储值

然而,如果不了解你想要实现什么,我不能保证这将解决你所有的问题。

英文:

I am unsure what you are trying to achieve. But your example code is guaranteed to block on the select statement.

The default case for a select is used to provide a fallback when either a specific read or write on a channel does not succeed. This means that in your code, the default case is always executed. No value is ever written into the channel before the select begins, thus the case statement is never run.

The code in the default case will never succeed and block indefinitely, because there is no space in the channel to store the value and nobody else is reading from it in any other goroutines.

A simple solution to your immediate problem would be:

stopSvr=make(chan bool, 1) // 1 slot buffer to store a value

However, without understanding what you want to achieve, I can't guarantee that this will solve all your problems.

huangapple
  • 本文由 发表于 2014年10月15日 01:14:31
  • 转载请务必保留本文链接:https://go.coder-hub.com/26366479.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定