How to make two functions calls f1(2)
and f1(1)
execute in parallel so that all the program would execute for 2 seconds not for 3.
package main
import (
"fmt"
"time"
)
// sleeps for `secs` seconds
func f1(secs time.Duration) (result string) {
fmt.Printf("waiting %V
", secs)
time.Sleep(secs * time.Second)
result = fmt.Sprintf("waited for %d seconds", secs)
return
}
// prints arg1, arg2
func f2(arg1, arg2 string) {
fmt.Println(arg1)
fmt.Println(arg2)
}
// this function executes for 3 seconds, because waits a lot
func runNotParallel() {
out1 := f1(2)
out2 := f1(1)
f2(out1, out2)
}
// golang parallel return functions
// todo: make it run so all the function will executes for 2 seconds not for 3
func runParallel() {
out1 := f1(2)
out2 := f1(1)
f2(out1, out2)
}
func main() {
runNotParallel()
runParallel()
}
I guess I can do it only with channels. Should I redefine function f1
or I can leave it as is and change only way I call it?
Use chan/goroutine
package main
import (
"fmt"
"time"
)
// sleeps for `secs` seconds
func f1(secs time.Duration) (result string) {
fmt.Printf("waiting %v
", secs)
time.Sleep(secs * time.Second)
result = fmt.Sprintf("waited for %v seconds", secs)
return
}
// prints arg1, arg2
func f2(arg1, arg2 string) {
fmt.Println(arg1)
fmt.Println(arg2)
}
// this function executes for 3 seconds, because waits a lot
func runNotParallel() {
out1 := f1(2)
out2 := f1(1)
f2(out1, out2)
}
// golang parallel return functions
// todo: make it run so all the function will executes for 2 seconds not for 3
func runParallel() {
out1 := make(chan string)
out2 := make(chan string)
go func() {
out1 <- f1(2)
}()
go func() {
out2 <- f1(1)
}()
f2(<-out1, <-out2)
}
func main() {
runNotParallel()
runParallel()
}
Another way you could do it is using WaitGroup
I wrote this utility function to help parallelize a group of functions:
import "sync"
// Parallelize parallelizes the function calls
func Parallelize(functions ...func()) {
var waitGroup sync.WaitGroup
waitGroup.Add(len(functions))
defer waitGroup.Wait()
for _, function := range functions {
go func(copy func()) {
defer waitGroup.Done()
copy()
}(function)
}
}
So in your case, we could do this
value1 := ""
value2 := ""
func1 := func() {
value1 = f1(2)
}
func2 = func() {
value2 = f1(1)
}
Parallelize(func1, func2)
f2(out1, out2)
If you wanted to use the Parallelize function, you can find it here https://github.com/shomali11/util