玉入れ
田中君:1投あたり2秒
鈴木君:1投あたり1秒
ルール
- 先に10球投げた方の勝ち → ゲーム終了
- 玉入れ先は別々
ポイント
- waitするスレッドを1として、1つでも並列スレッドが完了した場合、プログラムを終了させる。
package main
import (
"fmt"
"strconv"
"sync"
"time"
)
type Tomodachi struct {
name string
per_throw_time int
greeting string
}
var greeting = "よろしくお願いします"
var tanaka = Tomodachi{
name: "tanaka",
per_throw_time: 2,
greeting: greeting,
}
var suzuki = Tomodachi{
name: "suzuki",
per_throw_time: 1,
greeting: greeting,
}
var wg = sync.WaitGroup{}
func main() {
fmt.Printf("%vです。%v。\n", tanaka.name, greeting)
fmt.Printf("%vです。%v。\n", suzuki.name, greeting)
start_time := time.Now()
// 待つスレッドの数
wg.Add(1)
go tamaire(tanaka.name, tanaka.per_throw_time)
go tamaire(suzuki.name, suzuki.per_throw_time)
fmt.Println("start")
// スレッドから終わりの連絡を待つ。
wg.Wait()
// end_time := time.Now()
elapsed_time := time.Since(start_time)
fmt.Printf("経過時間 : %v\n", elapsed_time)
}
func tamaire(name string, per_throw_time int) {
for i := 1; i < 100; i++ {
time.Sleep(time.Duration(per_throw_time) * time.Second)
if i == 10 {
fmt.Printf("%v\n", time.Now())
fmt.Printf("%v君%v投目\n", name, i)
break
}
i := strconv.Itoa(i)
fmt.Printf("%v\n", time.Now())
fmt.Printf("%v君%v投目\n", name, i)
}
fmt.Printf("%v君の勝利!\n", name)
// メインスレッドに「僕は終わったよ」と伝える。
wg.Done()
}
実行結果
tanakaです。よろしくお願いします。
suzukiです。よろしくお願いします。
start
suzuki君1投目
tanaka君1投目
suzuki君2投目
suzuki君3投目
tanaka君2投目
suzuki君4投目
suzuki君5投目
tanaka君3投目
suzuki君6投目
suzuki君7投目
tanaka君4投目
suzuki君8投目
suzuki君9投目
tanaka君5投目
suzuki君10投目
suzuki君の勝利!
経過時間 : 10.0233975s
次に2人とも終了するまでゲームが終わらない場合
ポイント
- waitするスレッドを2とする。
package main
import (
"fmt"
"strconv"
"sync"
"time"
)
type Tomodachi struct {
name string
per_throw_time int
greeting string
}
var greeting = "よろしくお願いします"
var tanaka = Tomodachi{
name: "tanaka",
per_throw_time: 2,
greeting: greeting,
}
var suzuki = Tomodachi{
name: "suzuki",
per_throw_time: 1,
greeting: greeting,
}
var wg = sync.WaitGroup{}
func main() {
fmt.Printf("%vです。%v。\n", tanaka.name, greeting)
fmt.Printf("%vです。%v。\n", suzuki.name, greeting)
start_time := time.Now()
// 待つスレッドの数
wg.Add(2)
go tamaire(tanaka.name, tanaka.per_throw_time)
go tamaire(suzuki.name, suzuki.per_throw_time)
fmt.Println("start")
// スレッドから終わりの連絡を待つ。
wg.Wait()
wg.Wait()
// end_time := time.Now()
elapsed_time := time.Since(start_time)
fmt.Printf("経過時間 : %v\n", elapsed_time)
}
func tamaire(name string, per_throw_time int) {
for i := 1; i < 100; i++ {
time.Sleep(time.Duration(per_throw_time) * time.Second)
if i == 10 {
fmt.Printf("%v\n", time.Now())
fmt.Printf("%v君%v投目\n", name, i)
break
}
i := strconv.Itoa(i)
fmt.Printf("%v\n", time.Now())
fmt.Printf("%v君%v投目\n", name, i)
}
// fmt.Printf("%v君の勝利!\n", name)
fmt.Printf("%v君終了!\n", name)
// メインスレッドに「僕は終わったよ」と伝える。
wg.Done()
}
終了結果
tanakaです。よろしくお願いします。
suzukiです。よろしくお願いします。
start
2021-12-26 00:29:47.9075919 +0900 JST m=+1.003917701
suzuki君1投目
2021-12-26 00:29:48.9075828 +0900 JST m=+2.003908601
tanaka君1投目
2021-12-26 00:29:48.9463528 +0900 JST m=+2.042678601
suzuki君2投目
2021-12-26 00:29:49.94648 +0900 JST m=+3.042805801
suzuki君3投目
2021-12-26 00:29:50.9080411 +0900 JST m=+4.004366901
tanaka君2投目
2021-12-26 00:29:50.9578967 +0900 JST m=+4.054222501
suzuki君4投目
2021-12-26 00:29:51.9588457 +0900 JST m=+5.055171501
suzuki君5投目
2021-12-26 00:29:52.9085968 +0900 JST m=+6.004922601
tanaka君3投目
2021-12-26 00:29:52.9710026 +0900 JST m=+6.067328401
suzuki君6投目
2021-12-26 00:29:53.9724243 +0900 JST m=+7.068750101
suzuki君7投目
2021-12-26 00:29:54.9105403 +0900 JST m=+8.006866101
tanaka君4投目
2021-12-26 00:29:54.973832 +0900 JST m=+8.070157801
suzuki君8投目
2021-12-26 00:29:55.9756013 +0900 JST m=+9.071927101
suzuki君9投目
2021-12-26 00:29:56.9254739 +0900 JST m=+10.021799701
tanaka君5投目
2021-12-26 00:29:56.9756559 +0900 JST m=+10.071981701
suzuki君10投目
suzuki君終了!
2021-12-26 00:29:58.9264477 +0900 JST m=+12.022773501
tanaka君6投目
2021-12-26 00:30:00.9271847 +0900 JST m=+14.023510501
tanaka君7投目
2021-12-26 00:30:02.9272481 +0900 JST m=+16.023573901
tanaka君8投目
2021-12-26 00:30:04.9276392 +0900 JST m=+18.023965001
tanaka君9投目
2021-12-26 00:30:06.9292777 +0900 JST m=+20.025603501
tanaka君10投目
tanaka君終了!
経過時間 : 20.0232072s
最後に念のため、wg.wait(0)した時の結果を確認
package main
import (
"fmt"
"strconv"
"sync"
"time"
)
type Tomodachi struct {
name string
per_throw_time int
greeting string
}
var greeting = "よろしくお願いします"
var tanaka = Tomodachi{
name: "tanaka",
per_throw_time: 2,
greeting: greeting,
}
var suzuki = Tomodachi{
name: "suzuki",
per_throw_time: 1,
greeting: greeting,
}
var wg = sync.WaitGroup{}
func main() {
fmt.Printf("%vです。%v。\n", tanaka.name, greeting)
fmt.Printf("%vです。%v。\n", suzuki.name, greeting)
start_time := time.Now()
// 待つスレッドの数
wg.Add(0)
go tamaire(tanaka.name, tanaka.per_throw_time)
go tamaire(suzuki.name, suzuki.per_throw_time)
fmt.Println("start")
// スレッドから終わりの連絡を待つ。
wg.Wait()
wg.Wait()
// end_time := time.Now()
elapsed_time := time.Since(start_time)
fmt.Printf("経過時間 : %v\n", elapsed_time)
}
func tamaire(name string, per_throw_time int) {
for i := 1; i < 100; i++ {
time.Sleep(time.Duration(per_throw_time) * time.Second)
if i == 10 {
fmt.Printf("%v\n", time.Now())
fmt.Printf("%v君%v投目\n", name, i)
break
}
i := strconv.Itoa(i)
fmt.Printf("%v\n", time.Now())
fmt.Printf("%v君%v投目\n", name, i)
}
// fmt.Printf("%v君の勝利!\n", name)
fmt.Printf("%v君終了!\n", name)
// メインスレッドに「僕は終わったよ」と伝える。
wg.Done()
}
実行結果
tanakaです。よろしくお願いします。
suzukiです。よろしくお願いします。
start
経過時間 : 773.9µs
goroutineが始まる前にメインスレッドが終了。