Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Multithreading 如何在不等待另一个goroutine设置的情况下读取频道?_Multithreading_Go_Goroutine - Fatal编程技术网

Multithreading 如何在不等待另一个goroutine设置的情况下读取频道?

Multithreading 如何在不等待另一个goroutine设置的情况下读取频道?,multithreading,go,goroutine,Multithreading,Go,Goroutine,我在goroutine中使用频道时遇到问题 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++ {

我在goroutine中使用频道时遇到问题

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)
    }
}
我需要在不等待测试变量更新的情况下读取线程。 现在每个readChan()都在等待initChan()更新测试变量


是否可以使readChan()线程一次工作而不必为每个线程等待initChan()

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
        }
    }
}
var测试=make(chan字符串)
var mapChan=make(映射[int]chan字符串)
变量计数=3
func main(){
开始
去迪蒙
对于i:=0;i消息:=如果我正确理解了您的问题,此解决方案可能会有所帮助。我使用了一个大小为1的缓冲通道,以便作为发送方的goroutine在非缓冲通道的情况下永远不会被阻止。您可以阅读有关通道的更多信息:

主程序包
进口(
“日志”
“strconv”
“同步”
“时间”
)
//大小为1的缓冲通道保证数据的延迟传输
//一旦goroutine发送到频道,接收者goroutine就会将其删除
//然后,接收方goroutine执行该工作,但发送方goroutine未被阻止
//因为在接收者收到它后,大小再次为0,但可能尚未处理它
var测试=制造(chan字符串,1)
func main(){
var wg sync.WaitGroup
工作组.添加(2)
//在主goroutine返回之前,等待其他goroutine完成
延迟工作组等待()
go initChan(&wg)
go readChan(&wg)
}
func initChan(wg*sync.WaitGroup){
推迟工作组完成()
对于i:=0;i<100;i++{
//连续发送

test@Stairdeck如果我引用您的问题,那么我的解决方案非常适合。通道被读取并处理(例如打印到标准输出)而负责发送到通道的另一个goroutine没有被阻止。不,我需要同时从所有线程输出,甚至测试变量也没有更新。在我的示例中,像3行迭代num:0,每个线程一行这样的输出。你可以构建这个检查输出。我已经编辑了答案,我认为这解决了你的问题。@StairdeckI需要所有线程同时输出,即使测试变量也不会更新。输出如3行迭代num:0,在我的示例中,每个线程一行。我已根据您的要求更新了我的答案。对于测试通道上的每个发送,所有侦听线程都将接收。希望这能解决您的问题。
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
        }
    }
}
package main

import (
    "log"
    "strconv"
    "sync"
    "time"
)

// Buffered channel with size 1 guarantees delayed delivery of data
// As soon as the goroutine sends to the channel, the reciever goroutine dequeus it
// Then the reciver goroutines does the work, but the sender goroutine isn't blocked
// As the size is again 0 after the reciever recieved it but might haven't processed it yet
var test = make(chan string, 1)

func main() {
    var wg sync.WaitGroup
    wg.Add(2)
    // Waits for other goroutines to complete before the main goroutine returns
    defer wg.Wait()
    go initChan(&wg)
    go readChan(&wg)
}

func initChan(wg *sync.WaitGroup) {
    defer wg.Done()
    for i := 0; i < 100; i++ {
        // Sends continuously
        test <- "Iteration num: " + strconv.Itoa(i)
        time.Sleep(time.Second * 5)
    }
    close(test)
}

func readChan(wg *sync.WaitGroup) {
    defer wg.Done()
    var message string
    var ok bool
    // Reciever deques the value as soon as it recieves it
    // But might take time to proceed
    for {
        select {
        case message, ok = <-test:
            // If channel is closed
            if ok == false {
                return
            }
            log.Println(message)
        default:
            log.Println(message)
        }
    }
}