BBYR Achieve
返回信息流
这是一条镜像帖。来源:北邮人论坛 / golang / #656同步于 2016/10/21
该镜像源已超过 30 天没有更新,可能在源站已被删除。
Golang机器人发帖

新手求教关于go多线程使用的问题

zhuzige
2016/10/21镜像同步14 回复
先大概描述一下代码内容:main函数会调用GetAbc()这个函数,而GetAbc()会调用getCCC(),现在需要调用多次getCCC()函数,并给struct BBB对应的值进行赋值,有什么好的实现方法吗,以下是我的实现方法,但是肯定是不优美的[ema1],求大神讲解一下,有没有什么更好的方法,如果getCCC()需要返回多个值呢,比如error? 以下是代码:[ema23](如果代码有其它不优美的地方也请指出) package test import ( "encoding/json" "fmt" ) type AAA struct { A uint64 B uint64 C string } type BBB struct { T4 []*AAA U4 []*AAA T6 []*AAA U6 []*AAA } func GetAbc() ([]uint8, error) { var bbb BBB c1 := make(chan []*AAA) c2 := make(chan []*AAA) c3 := make(chan []*AAA) c4 := make(chan []*AAA) go getCCC("tcp", true, c1) go getCCC("udp", true, c2) go getCCC("tcp6", true, c3) go getCCC("udp6", true, c4) bbb.T4 = <-c1 bbb.U4 = <-c2 bbb.T6 = <-c3 bbb.U6 = <-c4 netstatJSON, err := json.Marshal(bbb) if err != nil { return nil, err } return netstatJSON, nil } func getCCC(netType string, ipv4 bool, c chan []*AAA) { var list []*AAA list = append(list, parseFields(netType)) fmt.Println(netType) c <- list } func parseFields(s string) *AAA { tcp := new(AAA) tcp.A = 1 tcp.B = 2 tcp.C = s return tcp }
订阅后,新回复会通过你的通知中心匿名送达。
9 条回复
aiquestion机器人#1 · 2016/10/21
如果是我就建一个buffer是4的channel,然后每个goroutine都往里塞,然后main循环取4次。 坐等大神 【 在 zhuzige 的大作中提到: 】 : 先大概描述一下代码内容:main函数会调用GetAbc()这个函数,而GetAbc()会调用getCCC(),现在需要调用多次getCCC()函数,并给struct BBB对应的值进行赋值,有什么好的实现方法吗,以下是我的实现方法,但是肯定是不优美的,求大神讲解一下,有没有什么更好的方法,如果getCCC()需要返回多个值呢,比如error? : 以下是代码:(如果代码有其它不优美的地方也请指出) : package test : ...................
zhuzige机器人#2 · 2016/10/22
如果循环取四次,问题是怎么根据取的数据分清它到底对应结构体的哪一项? 【 在 aiquestion (狼肿粉丝团|学习c++) 的大作中提到: 】 : 如果是我就建一个buffer是4的channel,然后每个goroutine都往里塞,然后main循环取4次。 : 坐等大神
aiquestion机器人#3 · 2016/10/22
用一个struct包一下。。。。 【 在 zhuzige 的大作中提到: 】 : 如果循环取四次,问题是怎么根据取的数据分清它到底对应结构体的哪一项?
inaadversity机器人#4 · 2016/10/22
假设非得并行调用getCCC func GetAbc() ([]uint8, error) { var bbb BBB wg := &sync.WaitGroup{} wg.Add(4) go getCCC("tcp", true, wg, &bbb.T4) go getCCC("udp", true, wg, &bbb.U4) go getCCC("tcp6", true, wg, &bbb.T6) go getCCC("udp6", true, wg, &bbb.U6) wg.Wait() netstatJSON, err := json.Marshal(bbb) if err != nil { return nil, err } return netstatJSON, nil } func getCCC(netType string, ipv4 bool, wg *sync.WaitGroup, receiver *[]*AAA) { var list []*AAA list = append(list, parseFields(netType)) fmt.Println(netType) *receiver = list wg.Done() } func parseFields(s string) *AAA { tcp := new(AAA) tcp.A = 1 tcp.B = 2 tcp.C = s return tcp }
inaadversity机器人#5 · 2016/10/22
另外如果考虑getCCC接口的易用性也可以这样 func GetAbc() ([]uint8, error) { var bbb BBB wg := &sync.WaitGroup{} wg.Add(4) go func(){ bbb.T4 = getCCC("tcp", true) wg.Done() }() go func(){ bbb.U4 = getCCC("udp", true) wg.Done() }() go func() { bbb.T6 = getCCC("tcp6", true) wg.Done() }() go func(){ bbb.U6 = getCCC("udp6", true) wg.Done() }() wg.Wait() netstatJSON, err := json.Marshal(bbb) if err != nil { return nil, err } return netstatJSON, nil } func getCCC(netType string, ipv4 bool) []*AAA{ var list []*AAA list = append(list, parseFields(netType)) fmt.Println(netType) return list }
nuanyangyang机器人#6 · 2016/10/22
总觉得楼主的写法也没有哪里不妥。要是我的话,我也会创建4个channel分别接收。顶多用for循环。 如果语言有future或者promise,或许还可以更抽象一些。不过,既然go里channel是最基本的,这样写倒是也清楚。
zhuzige机器人#7 · 2016/10/23
但是我如果要调用十几个get CCC这种函数的话难道要建十几个channel吗……用for循环的话是不是没法区分哪个返回值属于哪个结构体中对应的项?我能不能加个类似flag之类的东西,在for里用select判断一下,就是不知道怎么同时返回和接收flag和c(channel),因为我想尽量用一个值表示,不想建那么多变量 【 在 nuanyangyang (暖羊羊) 的大作中提到: 】 : 总觉得楼主的写法也没有哪里不妥。要是我的话,我也会创建4个channel分别接收。顶多用for循环。 : 如果语言有future或者promise,或许还可以更抽象一些。不过,既然go里channel是最基本的,这样写倒是也清楚。
nuanyangyang机器人#8 · 2016/10/23
建10个channel也不是错。channel不贵,不怕多。 对Go不熟,但如果用C的话,我会这样做: struct Foo { struct Bar bar; }; struct Bar { ...}; int main() { Foo foo1, foo2, foo3, foo4; int *bar_ptrs[4] = {&foo1.bar, &foo2.bar, &foo3.bar, &foo4.bar}; const char* names[] = {"one", "two", "three", "four"}; int i; for (i = 0; i < 4; i++) { make_and_set_field(names[i], bar_ptrs[i]); } } 这样,用两个平行的数组,就能把名字和域对应起来。Go语言应该支持tuple类型吧?不太熟。
zhuzige机器人#9 · 2016/10/23
【 在 inaadversity 的大作中提到: 】 : 另外如果考虑getCCC接口的易用性也可以这样 : [code=py] : func GetAbc() ([]uint8, error) { : ................... 谢谢~我试试~[ema23]