标签: channel

重用 Go 通道会导致死锁

我是新手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)语句可以解决问题,...但是

僵局何时何地发生?

concurrency channel go

0
推荐指数
1
解决办法
322
查看次数

Golang,如何分享价值 - 消息或互斥?

我已经完成了简单的基准测试,其中一个在消息传递和锁定共享值方面更有效.

首先,请检查下面的代码.

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)

mutex channel go

0
推荐指数
1
解决办法
3196
查看次数

如何在同一循环内向/从通道发送和接收值?

下面是一个例子:

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)

难道我做错了什么?

channel go goroutine

0
推荐指数
1
解决办法
1888
查看次数

关闭Go中的频道

我正在学习通道如何在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都睡着了 - 僵局!

当我不关闭频道.究竟是什么导致了僵局?当我不关闭它时,为什么我不能从其容量边界的频道接收到它?

channel go

0
推荐指数
1
解决办法
1114
查看次数

如何在Go中复用通道输出

我正在寻找一种解决方案,可以多路传输一些通道输出。

我有一个数据源,它是从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)

channel go multiplexing

0
推荐指数
1
解决办法
665
查看次数

Golang缓冲通道甚至在发送之前接收数据

我对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)

concurrency channel go

0
推荐指数
1
解决办法
70
查看次数

为什么goroutine中的未缓冲通道得到了这个顺序

我正在使用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)

我很困惑,为什么内部无缓冲通道只是在不等待读取的情况下运行

channel go goroutine

0
推荐指数
1
解决办法
39
查看次数

如何暂停和恢复 goroutine?

我正在尝试暂停和恢复 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)

concurrency channel go goroutine

0
推荐指数
1
解决办法
333
查看次数

未被“选择”的频道会发生什么?

根据GOPL,“选择等待直到某些情况的通信准备好继续”,那么未选择的通道会发生什么?此外,向“未选择”通道发送消息的 goroutine 是否会卡住从而导致 goroutine 泄漏?

还是因为“unselected”通道不可达,被GC回收(立即?),卡住的goroutine也被回收?

concurrency channel go

0
推荐指数
1
解决办法
120
查看次数

goroutine调用中通道接收操作符的阻塞行为

go DelegateWork(mr, <-mr.impl.readyWorkers, jobArgs)    
Run Code Online (Sandbox Code Playgroud)

在上面的例子中,通道接收操作符是否会导致调用者或被调用的 goroutine 阻塞?

channel go goroutine

0
推荐指数
1
解决办法
54
查看次数

标签 统计

channel ×10

go ×10

concurrency ×4

goroutine ×4

multiplexing ×1

mutex ×1