multithreading - 如何在不等待另一个 goroutine 中设置的情况下读取 channel ?

标签 multithreading go goroutine

我在 goroutine 中使用 channel 时遇到问题。

var test = make(chan string)

func main() {
    go initChan()

    for i := 0; i < 2; i++ {
        go readChan()
    }

    var input string
    fmt.Scanln(&input)
}

func initChan() {
    for i := 0; i < 100; i++ {
        test <- "Iteration num: " + strconv.Itoa(i)
        time.Sleep(time.Second * 5)
    }
}

func readChan() {
    for {
        message := <- test
        log.Println(message)
    }
}

输出:

2019/12/24 08:21:17 Iteration num: 0
2019/12/24 08:21:22 Iteration num: 1
2019/12/24 08:21:27 Iteration num: 2
2019/12/24 08:21:32 Iteration num: 3
2019/12/24 08:21:37 Iteration num: 4
2019/12/24 08:21:42 Iteration num: 5
................................

我需要线程读取而不等待测试变量的更新。 现在每个 readChan() 都在等待 initChan() 更新测试变量。

是否可以让 readChan() 线程一次性工作,而无需为每个线程等待 initChan() ?

最佳答案

创建了一个恶魔,它将所有消息从测试 channel 推送到所有其他监听例程。

var test = make(chan string)

var mapChan = make(map[int]chan string)
var count = 3

func main() {
    go initChan()
    go deamon()
    for i := 0; i < count; i++ {
        mapChan[i] = make(chan string)
        go readChan(i)
    }

    var input string
    fmt.Scanln(&input)
}

func deamon() {
    for {
        message := <-test
        for i := 0; i < count; i++ {
            mapChan[i] <- message
        }
    }
}

func initChan() {
    for i := 0; i < 100; i++ {
        test <- "Iteration num: " + strconv.Itoa(i)
        time.Sleep(time.Second * 1)
    }
}

func readChan(i int) {
    for {
        select {

        case message := <-mapChan[i]:
            log.Println(message)
        default:
            // Do for not when written on channel
        }
    }
}

关于multithreading - 如何在不等待另一个 goroutine 中设置的情况下读取 channel ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59463846/

相关文章:

java - run 和 equals 方法有奇怪的事情或者我做的任何错误

c++ - 在 QThreadPool 中执行槽

postgresql - 在gorm中获取结构中的嵌套对象

go - 什么时候 int 是 64 位的?

concurrency - goroutines 是如何工作的? (或 : goroutines and OS threads relation)

c - 非阻塞 native 文件访问 - C 中的单线程守护进程?

c# - 在 C# 中命名同步对象以用于争用分析

go - 如何在处理结果时正确关闭 Goroutines 中的共享 channel

Golang 工作池实现意外工作

go - 使用同步/原子包进行同步的代码中的意外行为