- r - 以节省内存的方式增长 data.frame
- ruby-on-rails - ruby/ruby on rails 内存泄漏检测
- android - 无法解析导入android.support.v7.app
- UNIX 域套接字与共享内存(映射文件)
我遇到了 Go channel 的奇怪行为。问题描述如下。
package main
import "fmt"
func main() {
ch := make(chan int)
fmt.Println("len:", len(ch))
fmt.Println("cap:", cap(ch))
fmt.Println("is nil:", ch == nil)
go func(ch chan int){
ch <- 233
}(ch)
fmt.Println(<- ch)
}
当我运行上面的代码时,我得到了这样的结果:
len: 0
cap: 0
is nil: false
233
channel ch 的 len 和 cap 看起来很奇怪,但代码仍然有效。但是当我运行这段代码时:
package main
import "fmt"
func main() {
ch := make(chan int)
fmt.Println("len:", len(ch))
fmt.Println("cap:", cap(ch))
fmt.Println("is nil:", ch == nil)
ch <- 233 // Here changes!
fmt.Println(<- ch)
}
结果变成了:长度:0上限:0为零:假 fatal error :所有 goroutines 都睡着了 - 死锁!
goroutine 1 [chan send]:
main.main()
/tmp/sandbox640280398/main.go:12 +0x340
更重要的是,当我像下面这样更改第二个代码片段时:包主
import "fmt"
func main() {
ch := make(chan int, 1) //Here changes!
fmt.Println("len:", len(ch))
fmt.Println("cap:", cap(ch))
fmt.Println("is nil:", ch == nil)
ch <- 233
fmt.Println(<- ch)
}
事情又成功了,我得到了:
len: 0
cap: 1
is nil: false
233
所以,谁能告诉我以下问题:
为什么 make(chan int) 返回具有 零 len 和 零 上限的 channel ,但在第一个代码中仍然可以正常工作一 block ?
为什么第二个代码在 main 函数中使用 channel 而不是新的 goroutine 导致死锁?
为什么我在第三段代码中给make加一个cap参数就可以解决问题?
channel (第一和第二代码)与 nil channel 有什么区别?
最佳答案
您可以创建两种类型的 channel :缓冲 channel 和非缓冲 channel 。
缓冲 channel 是那些具有容量的 channel :make(chan int, 10)
缓冲 channel 允许您向其中发送与其容量相同数量的消息而不会被阻塞。
无缓冲 channel 没有容量,这就是为什么您的发送 goroutine 将被阻塞,直到另一个 goroutine 收到它。
1. 无缓冲 channel 。在新的 goroutine 向它发送消息之前,你的主 goroutine 在从 channel 接收时被阻塞。
2. 因为您使用的是无缓冲 channel ,所以您的发送 goroutine 会被阻塞,直到另一个 goroutine 接收到它,但是除了主 goroutine 之外您没有其他 goroutine,因此程序处于死锁状态。
3. 由于缓冲 goroutine。它的容量为 1,因此向它发送一条消息然后在同一个 goroutine 中接收它不会有问题。但是,如果您尝试向它发送超过 1 条消息,您将被阻止。 ch <- 233; ch <- 233
- 此代码将导致死锁。
4. 明白您的意思...,但是如果您尝试接收或发送到 nil channel ,您将被阻止:var ch chan int; <-ch
或 var ch chan int; ch <- 1
关于go - 与 make channel 相关的奇怪死锁,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45366954/
我有这种来自 Google map 自动完成的奇怪行为(或者我可能错过了某事)...想法?奇怪的: 您在输入中输入某物,例如“伦敦” 您按 [ENTER] 你按下 [CLEAR] 按钮 你点击进入'输
这段代码与《Learning Java》(Oracle Press Books)一书中的代码完全一样,但它不起作用。我不明白为什么它不起作用,它应该起作用。我用 OpenJDK 和 Sun JDK 7
示例 1 中究竟发生了什么?这是如何解析的? # doesnt split on , [String]::Join(",",("aaaaa,aaaaa,aaaaa,aaaaa,aaaaa,aa
我需要获得方程式系统的解决方案。为此,我使用函数sgesv_()。 一切都很好,它使我感到解决方案的正确结果。 但是我得到一个奇怪的警告。 警告:从不兼容的指针类型传递'sgesv_'的参数3 我正在
我目前在制作动画时遇到一个奇怪的问题: [UIView animateWithDuration:3 delay:0
alert('works'); $(window).load(function () { alert('does not work'); });
我的代码: public class MyTest { public class StringSorter implements Comparator { public
我正在学习 JavaScript。尝试理解代码, function foo (){ var a = b = {name: 'Hai'}; document.write(a.name +''
这个问题不太可能帮助任何 future 的访问者;它只与一个小的地理区域、一个特定的时间点或一个非常狭窄的情况有关,这些情况并不普遍适用于互联网的全局受众。为了帮助使这个问题更广泛地适用,visit
这按预期工作: [dgorur@ted ~]$ env -i env [dgorur@ted ~]$ 这样做: [dgorur@ted ~]$ env -i which date which: no
struct BLA { int size_; int size()const{ return size_; } } int x; BLA b[ 2 ]; BLA * p = &b[
我有以下代码: #test img {vertical-align: middle;} div#test { border: 1px solid green; height: 150px; li
我想大多数使用过 C/C++ 的人都对预处理器的工作原理有一定的直觉(或多或少)。直到今天我也是这么认为的,但事实证明我的直觉是错误的。故事是这样的: 今天我尝试了一些东西,但我无法解释结果。首先考虑
我想为 TnSettings 做 mock,是的,如果通过以下方法编写代码,它就可以工作,问题是我们需要为每个案例编写 mock 代码,如果我们只 mock 一次然后执行多个案例,那么第二个将报告异常
我的项目中有以下两个结构 typedef volatile struct { unsigned char rx_buf[MAX_UART_BUF]; //Input buffer over U
Regex rx = new Regex(@"[+-]"); string[] substrings = rx.Split(expression); expression = "-9a3dcb
我的两个应用程序遇到了一个奇怪的问题。这是设置: 两个 tomcat/java 应用程序,在同一个网络中运行,连接到相同的 MS-SQL-Server。一个应用程序,恰好按顺序位于 DMZ 中可从互联
我目前正在与 Android Api Lvl 8 上的 OnLongClickListener 作斗争。 拿这段代码: this.webView.setOnLongClickListener(new
这个问题不太可能帮助任何 future 的访问者;它只与一个小的地理区域、一个特定的时间点或一个非常狭窄的情况相关,这些情况并不普遍适用于互联网的全局受众。为了帮助使这个问题更广泛地适用,visit
只是遇到了奇怪的事情。我有以下代码: -(void)ImageDownloadCompleat { [self performSelectorOnMainThread:@selector(up
我是一名优秀的程序员,十分优秀!