我是新手golang(有Java并发背景)。考虑一下这种和平的代码:
package main
import "fmt"
func sendenum(num int, c chan int) {
c <- num
}
func main() {
c := make(chan int)
go sendenum(0, c)
x, y := <-c, <-c
fmt.Println(x, y)
}
Run Code Online (Sandbox Code Playgroud)
当我运行此代码时,我收到此错误
fatal error: all goroutines are asleep - deadlock!
goroutine 1 [chan receive]:
main.main()
/home/tarrsalah/src/go/src/github.com/tarrsalah/stackoverflow/chan_dead_lock.go:12 +0x90
exit status 2
Run Code Online (Sandbox Code Playgroud)
我知道,添加另一条go sendenum(0, c)语句可以解决问题,...但是
僵局何时何地发生?
我已经完成了简单的基准测试,其中一个在消息传递和锁定共享值方面更有效.
首先,请检查下面的代码.
package main
import (
"flag"
"fmt"
"math/rand"
"runtime"
"sync"
"time"
)
type Request struct {
Id int
ResChan chan Response
}
type Response struct {
Id int
Value int
}
func main() {
procNum := flag.Int("proc", 1, "Number of processes to use")
clientNum := flag.Int("client", 1, "Number of clients")
mode := flag.String("mode", "message", "message or mutex")
flag.Parse()
if *procNum > runtime.NumCPU() {
*procNum = runtime.NumCPU()
}
fmt.Println("proc:", *procNum)
fmt.Println("client:", *clientNum)
fmt.Println("mode:", *mode)
runtime.GOMAXPROCS(*procNum)
rand.Seed(time.Now().UnixNano())
var wg sync.WaitGroup
sharedValue …Run Code Online (Sandbox Code Playgroud) 下面是一个例子:
func main() {
c := make(chan int)
i := 0
go goroutine(c)
c <- i
time.Sleep(10 * time.Second)
}
func goroutine(c chan int) {
for {
num := <- c
fmt.Println(num)
num++
time.Sleep(1 * time.Second)
c <- num
}
}
Run Code Online (Sandbox Code Playgroud)
我在 goroutine 中尝试做的是从通道接收数字,打印它,递增并在一秒钟后将其发送回通道。在此之后,我想重复这个动作。
但因此,操作只进行一次。
输出:
0
Run Code Online (Sandbox Code Playgroud)
难道我做错了什么?
我正在学习通道如何在Go中工作,并且偶然发现了关闭频道的问题.这是来自A Tour of Go的修改示例,它生成n-1个斐波纳契数并通过通道发送它们,使通道容量的最后一个"元素"不被使用.
func fibonacci(n int, c chan int) {
x, y := 0, 1
for i := 0; i < n-1; i++ {
c <- x
x, y = y, x+y
}
// close(c) // It's commented out on purpose
}
func main() {
n := 10
c := make(chan int, n)
go fibonacci(n, c)
for i := 0; i < n; i++ {
_, ok := <-c
fmt.Println(ok)
}
}
Run Code Online (Sandbox Code Playgroud)
问题是我得到:
致命错误:所有goroutines都睡着了 - 僵局!
当我不关闭频道.究竟是什么导致了僵局?当我不关闭它时,为什么我不能从其容量边界的频道接收到它?
我正在寻找一种解决方案,可以多路传输一些通道输出。
我有一个数据源,它是从io.Reader我发送到单个通道的读取的。另一方面,我有一个从通道读取的websocket请求处理程序。现在,发生了两个客户端创建一个websocket连接的情况,这两个客户端都从同一通道读取内容,但是每个客户端仅获得部分消息。
代码示例(简体):
func (b *Bootloader) ReadLog() (<-chan []byte, error) {
if b.logCh != nil {
logrus.Warn("ReadLog called while channel already exists!")
return b.logCh, nil // This is where we get problems
}
b.logCh = make(chan []byte, 0)
go func() {
buf := make([]byte, 1024)
for {
n, err := b.p.Read(buf)
if err == nil {
msg := make([]byte, n)
copy(msg, buf[:n])
b.logCh <- msg
} else {
break
}
}
close(b.logCh)
b.logCh = nil
}()
return b.logCh, …Run Code Online (Sandbox Code Playgroud) 我对golang很新.今天在测试Golang如何在Golang中运行时,我感到非常困惑.
根据教程:
仅在缓冲区已满时才发送到缓冲的通道块.缓冲区为空时接收阻止.
我的测试程序如下所示:
package main
import "fmt"
func main() {
ch := make(chan int, 2)
go func(ch chan int) int {
for i := 0; i < 10; i++ {
fmt.Println("goroutine: GET ", <-ch)
}
return 1
}(ch)
for j := 0; j < 10; j++ {
ch <- j
fmt.Println("PUT into channel", j)
}
}
Run Code Online (Sandbox Code Playgroud)
我得到这样的输出:
PUT into channel 0
PUT into channel 1
goroutine: GET 0
goroutine: GET 1
goroutine: GET 2
PUT into channel 2
PUT …Run Code Online (Sandbox Code Playgroud) 我正在使用goroutine和通道编写一些golang并发代码,这是我的代码:
package main
import "fmt"
func main() {
in := make(chan int)
go func() {
fmt.Println("Adding num to channel")
in <- 1
fmt.Println("Done")
}()
val := <- in
fmt.Println(val)
}
Run Code Online (Sandbox Code Playgroud)
我认为我创建了一个无缓冲的通道,内部通道必须等待,直到外部通道读取它为止,并且输出可能像这样:
Adding num to channel
1
Done
Run Code Online (Sandbox Code Playgroud)
但实际上,输出为:
Adding num to channel
Done
1
Run Code Online (Sandbox Code Playgroud)
我很困惑,为什么内部无缓冲通道只是在不等待读取的情况下运行
我正在尝试暂停和恢复 groutine。我知道我可以sleep跑步,但我正在寻找就像一个按钮“暂停/恢复”而不是一个计时器。
这是我的尝试。我正在使用通道的阻塞功能来暂停,并select根据通道值切换要执行的内容。但是,输出总是Running在我的情况下。
func main() {
ctx := wctx{}
go func(ctx wctx) {
for {
time.Sleep(1 * time.Second)
select {
case <-ctx.pause:
fmt.Print("Paused")
<-ctx.pause
case <-ctx.resume:
fmt.Print("Resumed")
default:
fmt.Print("Running \n")
}
}
}(ctx)
ctx.pause <- struct{}{}
ctx.resume <- struct{}{}
}
type wctx struct {
pause chan struct{}
resume chan struct{}
}
Run Code Online (Sandbox Code Playgroud) 根据GOPL,“选择等待直到某些情况的通信准备好继续”,那么未选择的通道会发生什么?此外,向“未选择”通道发送消息的 goroutine 是否会卡住从而导致 goroutine 泄漏?
还是因为“unselected”通道不可达,被GC回收(立即?),卡住的goroutine也被回收?
go DelegateWork(mr, <-mr.impl.readyWorkers, jobArgs)
Run Code Online (Sandbox Code Playgroud)
在上面的例子中,通道接收操作符是否会导致调用者或被调用的 goroutine 阻塞?