两个goroutine并发之间的golang pass结构

两个goroutine并发之间的golang pass结构,go,struct,concurrency,goroutine,Go,Struct,Concurrency,Goroutine,我有两个函数,我想做的是在这两个函数之外有一个通道,第一个在go例程中运行并更新通道,然后第二个函数应该在通道中的项目进入时读取它们并执行其他操作。当通道中的所有项目完成时,go例程应该优雅地退出 有人能告诉我如何从同一频道获得两个围棋程序吗?这可能吗 像下面这样的东西 package main import ( "fmt" ) type Person struct { index int name string age int } func Upd

我有两个函数,我想做的是在这两个函数之外有一个通道,第一个在go例程中运行并更新通道,然后第二个函数应该在通道中的项目进入时读取它们并执行其他操作。当通道中的所有项目完成时,go例程应该优雅地退出

有人能告诉我如何从同一频道获得两个围棋程序吗?这可能吗

像下面这样的东西


package main

import (
    "fmt"
)

type Person struct {
    index int
    name  string
    age   int
}

func UpdatePeople(psn *chan Person, grNo int) {

    for i := 0; i < 5; i++ {
        psn := Person{
            index: 1,
            name:  "Shaun",
            age:   23,
        }
        fmt.Printf("Person: %v --- GoRoutineNumber: %v\n", psn, grNo)
    }

}

func WritePeople(psn *chan Person) {

    for i := 0; i < 5; i++ {
        psn := Person{
            index: 1,
            name:  "Shaun",
            age:   23,
        }
        fmt.Println("Writing People to DB", psn)
    }

}

func main() {

    //make channel of Person struct
    psnChan := make(chan Person)

    //I have a variable length in my program so lets say it's 6 in this case

    for i := 0; i < 6; i++ {

        /// I want to start a go routine here that writes to pointer of psnChan
        go UpdatePeople(&psnChan, i)

    }

    // I then want to read in from the channel as UpdatePeople is writing to it in a separate go routine
    for {

        _, received := <-psnChan
        if received == false {
            fmt.Println("Break out of 2nd loop")
            close(psnChan)
            break
        } else {

          go    WritePeople(&psnChan)

        }

    }
    fmt.Println("Finished")
}




包干管
进口(
“fmt”
)
类型Person结构{
索引整数
名称字符串
年龄智力
}
func UpdatePeople(psn*chan Person,grNo int){
对于i:=0;i<5;i++{
psn:=人{
索引:1,
姓名:“肖恩”,
年龄:23,,
}
fmt.Printf(“人员:%v--goroutinumber:%v\n”,psn,grNo)
}
}
func WritePeople(psn*chan个人){
对于i:=0;i<5;i++{
psn:=人{
索引:1,
姓名:“肖恩”,
年龄:23,,
}
fmt.Println(“将人员写入数据库”,psn)
}
}
func main(){
//制作人物结构的通道
psnChan:=制造(成龙人)
//我的程序中有一个可变的长度,所以在这种情况下假设它是6
对于i:=0;i<6;i++{
///我想在这里开始一个go例程,它写入psnChan的指针
go UpdatePeople(&psnChan,i)
}

//然后,当UpdatePeople在一个单独的go例程中写入时,我想从该频道读入 为了{
_,received:=正如Sergio指出的,主goroutine正在阻塞,因为它等待从psns通道读取,但没有任何内容写入它。在编写Go to only write同步函数时有一条很好的建议,另一条建议是负责创建通道的函数在关闭时进行控制。因此,我重新构造了请记住您写的内容:。此程序将慢慢查找Person对象,通过通道发送它们,并在运行时写入每个Person。如果您的用例不同,请告诉我们:)希望这会有所帮助。

正如Sergio指出的,主goroutine正在阻塞,因为它正在等待从psns通道读取,但没有写入任何内容它。在编写Go to only write同步函数时,有一条很好的建议,另一条建议是负责创建通道的函数在关闭时进行控制。因此,我对您编写的内容进行了一些重构,并牢记以下几点:。此程序将缓慢地查找Person对象,通过通道发送它们,然后编写每个Person对象n随它去。让我们知道您的用例是否不同:)希望这有帮助。

您不需要传递指向通道的指针。传递通道本身。“因为UpdatePeople在单独的go例程中向其写入”-UpdatePeople对通道不做任何事。这就是为什么读取操作会阻止主goroutine(通道中没有任何内容)您不需要向通道传递指针。只需传递通道本身。“因为UpdatePeople在一个单独的go例程中向其写入”-UpdatePeople不会对通道执行任何操作。这就是为什么读取操作会阻止主goroutine(通道中没有任何内容)谢谢你的icio。这是如此简单和优雅。这很有意义,几乎适用于我的用例。以你的例子来说,如果我需要用FindPeople将gofunc包装成for循环,我想我最终会陷入恐慌。我需要为每个go例程制作一片Chan吗?是的,如果你尝试关闭通道多次程序am会惊慌失措。如果你想启动多个独立的FindPeople,我们需要等待他们全部完成,然后再关闭我们的chan people。我们可以使用sync.WaitGroup这样做:哇,谢谢,这真的帮助了我“获得它”:-)最后..想把WritePerson(p)放进去是不是疯了也进入围棋程序?最终我希望速度加上在后台运行这两个围棋程序的能力,但我不确定这样做是否正确。你可以,但不能保证速度更快。如果你正在向数据库写入,一个好的起点可能是考虑你有多少并发写入r系统将支持-可能与您的进程可以打开到服务器的连接数有关。我的最后一个示例是每个进程的一次并发写入。如果我们同时支持最多3次写入,我们可能会使用与查找程序相同的工作模式:谢谢您的ICO。这非常简单和优雅。这使没有意义,几乎适用于我的用例。以你的例子来说,如果我需要用FindPeople将gofunc封装在for循环中,我想我最终会陷入恐慌。我需要为每个go例程制作一片Chan吗?是的,如果你尝试多次关闭频道,程序将陷入恐慌。如果你想启动多个独立的Find大家,我们需要等待他们全部完成,然后才能关闭我们的chan People。我们可以使用sync.WaitGroup来完成此操作,因此:哇,谢谢,这真的帮助了我“获得它”:-)最后..想把WritePerson(p)放到也进入围棋程序?最终我希望速度加上在后台运行这两个围棋程序的能力,但我不确定这样做是否正确。你可以,但不能保证速度更快。如果你正在向数据库写入,一个好的起点可能是考虑你有多少并发写入r系统将支持-可能与您的进程可以打开到服务器的连接数有关。我的最后一个示例是每个进程一次并发写入。如果我们同时支持最多3次写入,我们可能会使用与查找程序相同的工作模式: