英文:
Go-routines with channels not running parallely
问题
package main
import "time"
func main() {
stringCh := make(chan func() string)
go func() {
stringCh <- func() string {
return stringReturner()
}
close(stringCh)
}()
intCh := make(chan func() int)
go func() {
intCh <- func() int {
return intReturner()
}
close(intCh)
}()
str := (<-stringCh)()
print("Printing str: ", str,"\n\n")
num := (<-intCh)()
print("Printing int: ", num,"\n\n")
}
func intReturner() int {
time.Sleep(5 * time.Second)
print("Inside int returner\n\n")
return 1
}
func stringReturner() string {
time.Sleep(5 * time.Second)
print("Inside string returner\n\n")
return "abcd"
}
输出:
Inside string returner
Printing str: abcd
等待5秒
Inside int returner
Printing int: 1
https://play.golang.org/p/oE2ybs7Jo-W
为什么这段代码执行需要10秒而不是5秒?我们通过同时启动两个goroutine(一个用于stringReturner,一个用于intReturner)来并行调用,但为什么intReturner在stringReturner执行之后执行?
英文:
package main
import "time"
func main() {
stringCh := make(chan func() (string))
go func() {
stringCh <- func() (string) {
return stringReturner()
}
close(stringCh)
}()
intCh := make(chan func() (int))
go func() {
intCh <- func() (int) {
return intReturner()
}
close(intCh)
}()
str := (<-stringCh)()
print("Printing str: ", str,"\n\n")
num := (<-intCh)()
print("Printing int: ", num,"\n\n")
}
func intReturner()int{
time.Sleep(5 * time.Second)
print("Inside int returner\n\n");
return 1;
}
func stringReturner()string{
time.Sleep(5 * time.Second)
print("Inside string returner\n\n");
return "abcd";
}
Output:
Inside string returner
Printing str: abcd
WAIT OF 5 SECONDS
Inside int returner
Printing int: 1
https://play.golang.org/p/oE2ybs7Jo-W
Why is this coding taking 10 seconds to execute instead of 5? We are parallelizing the calls by spawning two go-routines right (1 for string returner and 1 for int returner), but why is the int returner executing after the string returner executes?
答案1
得分: 3
该通道返回一个带有延时的函数,并且这个函数按顺序调用。这就是为什么通常需要10秒的原因。
https://play.golang.org/p/UpHD7Ttw03R
英文:
The channel is returning function with sleep, and such function got called in sequential manner. That is why it will take 10s in general.
答案2
得分: 1
这是因为你只是并行地向通道写入数据,但是从通道读取数据是按顺序进行的。要解决这个问题,你可以使用单独的goroutine从两个通道读取数据。
var wg sync.WaitGroup
wg.Add(2)
go func() {
defer wg.Done()
str := (<-stringCh)()
print("打印字符串: ", str, "\n\n")
}()
go func() {
defer wg.Done()
num := (<-intCh)()
print("打印整数: ", num, "\n\n")
}()
wg.Wait()
英文:
Thats because you are only writing to the channels parallelly. But the read from the channels are happening one-after-the-other. To fix this, you can read from both channels from separate go routines
var wg sync.WaitGroup
wg.Add(2)
go func() {
defer wg.Done()
str := (<-stringCh)()
print("Printing str: ", str, "\n\n")
}()
go func() {
defer wg.Done()
num := (<-intCh)()
print("Printing int: ", num, "\n\n")
}()
wg.Wait()
答案3
得分: 1
根据建议,将sleep方法移入go routine以在5秒内同时运行两个函数:
package main
import "time"
func main() {
stringCh := make(chan func() string)
go func() {
time.Sleep(5 * time.Second)
stringCh <- func() string {
return stringReturner()
}
close(stringCh)
}()
intCh := make(chan func() int)
go func() {
time.Sleep(5 * time.Second)
intCh <- func() int {
return intReturner()
}
close(intCh)
}()
str := (<-stringCh)()
print("Printing str: ", str, "\n\n")
num := (<-intCh)()
print("Printing int: ", num, "\n\n")
}
func intReturner() int {
print("Inside int returner\n\n")
return 1
}
func stringReturner() string {
print("Inside string returner\n\n")
return "abcd"
}
输出:
Inside string returner
Printing str: abcd
Inside int returner
Printing int: 1
英文:
Based on the suggestions moving the sleep method into go routine to run both functions concurrently in 5s:
package main
import "time"
func main() {
stringCh := make(chan func() string)
go func() {
time.Sleep(5 * time.Second)
stringCh <- func() string {
return stringReturner()
}
close(stringCh)
}()
intCh := make(chan func() int)
go func() {
time.Sleep(5 * time.Second)
intCh <- func() int {
return intReturner()
}
close(intCh)
}()
str := (<-stringCh)()
print("Printing str: ", str, "\n\n")
num := (<-intCh)()
print("Printing int: ", num, "\n\n")
}
func intReturner() int {
print("Inside int returner\n\n")
return 1
}
func stringReturner() string {
print("Inside string returner\n\n")
return "abcd"
}
Output:
Inside string returner
Printing str: abcd
Inside int returner
Printing int: 1
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论