先輩からお題が出されたので、忘れないように記載しておく
お題
Sleep関数を2秒以内に50回実施して、停止した最大、最小、平均ミリ秒数を表示してください
package main
import (
"math/rand"
"time"
"fmt"
)
func Sleep(i chan int) {
r := rand.Intn(500) + 100 // 止まるミリ秒数の定義.ランダム数
time.Sleep(time.Duration(r) * time.Millisecond) // 止まるミリ秒数の定義
fmt.Printf("I Slept %d millseconds. \n", r)
i <- r
}
func main() {
rand.Seed(time.Now().UnixNano())
// Sleep関数を2秒以内に50回実施して、停止した最大、最小、平均ミリ秒数を表示してください
}
自分の回答
package main
import (
"math/rand"
"time"
"fmt"
"sync"
"strconv"
)
func Sleep(i chan int) {
r := rand.Intn(500) + 100 // 止まるミリ秒数の定義.ランダム数
time.Sleep(time.Duration(r) * time.Millisecond) // 止まるミリ秒数の定義
fmt.Printf("I Slept %d millseconds. \n", r)
i <- r
}
func max(a []int) int {
max := a[0]
for _, i := range a {
if i > max {
max = i
}
}
return max
}
func min(a []int) int {
min := a[0]
for _, i := range a {
if i < min {
min = i
}
}
return min
}
func avg(a []int) int {
len := len(a)
sum := 0
for _, i := range a {
sum += i
}
return sum / len
}
func main() {
rand.Seed(time.Now().UnixNano())
// Sleep関数を2秒以内に50回実施して、停止した最大、最小、平均ミリ秒数を表示してください
// チャネルを用意
ch := make(chan int)
finished := make(chan int)
// Sleep関数を50回、並列処理で実行
wg := &sync.WaitGroup{}
for i := 0 ; i < 50 ; i++ {
wg.Add(1)
go func() {
Sleep(ch)
wg.Done()
}()
}
// 全ての並行処理が完了するのを待つ、完了次第、本スレッドに通知
go func(){
wg.Wait()
finished <- 1
}()
// 本スレッドで、並列で実行した結果を受け取る
results := []int{}
LOOP:
for {
select {
case v := <- ch:
results = append(results, v)
case <- finished:
break LOOP
}
}
// 結果の集計
fmt.Println("件数:" + strconv.Itoa(len(results)))
fmt.Println("最大:" + strconv.Itoa(max(results)))
fmt.Println("最小:" + strconv.Itoa(min(results)))
fmt.Println("平均:" + strconv.Itoa(avg(results)))
}
実行結果
件数:50
最大:573
最小:108
平均:311
「ここはこうした方が良い」など、ありましたらコメントいただければ幸いです。
別の方法も考えてみた
チャネルに結果を溜め込んで、完了後に取り出して集計する、今回のはこれで十分っぽい。
package main
import (
"math/rand"
"time"
"fmt"
"sync"
"strconv"
)
func Sleep(i chan int) {
r := rand.Intn(500) + 100 // 止まるミリ秒数の定義.ランダム数
time.Sleep(time.Duration(r) * time.Millisecond) // 止まるミリ秒数の定義
fmt.Printf("I Slept %d millseconds. \n", r)
i <- r
}
func max(a []int) int {
max := a[0]
for _, i := range a {
if i > max {
max = i
}
}
return max
}
func min(a []int) int {
min := a[0]
for _, i := range a {
if i < min {
min = i
}
}
return min
}
func avg(a []int) int {
l := len(a)
sum := 0
for _, i := range a {
sum += i
}
return sum / l
}
func main() {
rand.Seed(time.Now().UnixNano())
// Sleep関数を2秒以内に50回実施して、停止した最大、最小、平均ミリ秒数を表示してください
// チャネルを用意
ch := make(chan int, 50)
// Sleep関数を50回、並列処理で実行
wg := &sync.WaitGroup{}
for i := 0 ; i < 50 ; i++ {
wg.Add(1)
go func() {
Sleep(ch)
wg.Done()
}()
}
// 全ての並行処理が完了するのを待つ
wg.Wait()
close(ch)
// 並列で実行した結果を受け取る
results := []int{}
for v := range ch {
results = append(results, v)
}
// 結果の集計
fmt.Println("件数:" + strconv.Itoa(len(results)))
fmt.Println("最大:" + strconv.Itoa(max(results)))
fmt.Println("最小:" + strconv.Itoa(min(results)))
fmt.Println("平均:" + strconv.Itoa(avg(results)))
}