go入门(channel 理解)龟兔赛跑

1.乌龟每秒跑10cm,兔子每秒跑20cm;
2.兔子看到乌龟比自己落后1m,就开始睡20s.
3.跑道20m长
问最后谁赢了?

其实在go语言实现一个多线程不要太简单,不过人家叫做协程。用关键字go 就可以开启协程,多协程中通信用到最方便的方式还是channel。话不多说上代码

package main

import (
	"fmt"
	"sync"
	"time"
)
//同步标志
var wg sync.WaitGroup
//跑道20m
var total = 2000
//落后1m
var distance = 100
//兔子每秒跑20cm
var rabbitSpeed = 20
//睡20s
var rabbitSleepCount = 20
//乌龟每秒跑10cm
var tortoiseSpeed = 10

func main() {
	wg.Add(2)
	fmt.Printf("赛道总长 %d cm,兔子速度 %d cm/s乌龟速度 %d cm/s\n",total,rabbitSpeed,tortoiseSpeed)
	fmt.Print("比赛开始------\n")
	//构建通道传递乌龟距离
	t := make(chan int, 20)
	go rabbit(t)
	go tortoise(t)
	wg.Wait()
	close(t)
}

//兔子
func rabbit(t chan int) {
	fmt.Print("兔子起跑\n")
	var cm = 0
	var sleepCount = 0
	for true {
		time.Sleep(time.Second * 1)
		//获取乌龟的距离
		v := <-t
		//睡觉未结束
		if sleepCount > 0 {
			sleepCount--
			//继续下次
			fmt.Printf("兔子睡觉 %d s\n", rabbitSleepCount-sleepCount)
			continue
		}

		//每秒跑20cm
		cm += rabbitSpeed
		fmt.Printf("兔子跑了 %d cm\n", cm)

		//跑完停止 20*100cm
		if cm >= total {
			fmt.Print("兔子到达终点\n")
			wg.Done()
			break
		}

		//落后1m *100
		if cm-v >= distance {
			sleepCount = rabbitSleepCount
			fmt.Print("兔子开始睡觉\n")
		}
	}
}

//乌龟
func tortoise(t chan int) {
	var cm = 0
	fmt.Print("乌龟起跑\n")
	for true {
		time.Sleep(time.Second * 1)
		//每秒跑10cm
		cm += tortoiseSpeed
		fmt.Printf("乌龟跑了 %d cm\n", cm)
		t <- cm
		//跑完停止 20*100cm
		if cm >= total {
			fmt.Print("乌龟到达终点\n")
			wg.Done()
			break
		}
	}
}

结果如下
在这里插入图片描述

在这里插入图片描述

补记,这个使用chanel是一种解法,还有一种,使用共享变量

package main

import (
	"fmt"
	"sync"
	"sync/atomic"
	"time"
)



var  distance int32 = 0

var waitFlag sync.WaitGroup
var runFlag sync.WaitGroup
var lock sync.Mutex

//跑道20m
const total int32 = 2000

const timerIntervals  = time.Second *1

//动物接口
type Animal interface {
	 run()
 }

//兔子对象
type Rabbit struct {
	speed int32
	distance int32
	sleepCount int32
}

func (r Rabbit) run(){
	var cm int32 = 0
	fmt.Print("兔子就绪\n")
	runFlag.Wait()
	fmt.Print("兔子起跑\n")
	var sleepCount int32 = 0
	for true {
		time.Sleep(timerIntervals  * 1)
		//获取乌龟的距离
		var v = getDistance()
		//睡觉未结束
		if sleepCount > 0 {
			sleepCount--
			//继续下次
			fmt.Printf("兔子睡觉 %d s\n", r.sleepCount-sleepCount)
			continue
		}

		//每秒跑20cm
		cm += r.speed
		fmt.Printf("兔子跑了 %d cm\n", cm)

		//跑完停止 20*100cm
		if cm >= total {
			fmt.Println("兔子到达终点",time.Now())
			waitFlag.Done()
			break
		}

		//落后1m *100
		if cm-v>= r.distance {
			sleepCount = r.sleepCount
			fmt.Print("兔子开始睡觉\n")
		}
	}
}

type Tortoise struct {
	speed int32

}
func (t Tortoise) run(){
	var cm int32 = 0
	fmt.Print("乌龟就绪\n")
	runFlag.Wait()
	fmt.Print("乌龟起跑\n")
	for true {
		time.Sleep(timerIntervals)
		//每秒跑10cm
		cm += t.speed
		fmt.Printf("乌龟跑了 %d cm\n", cm)
		pullDistance(t.speed)
		//跑完停止 20*100cm
		if cm >= total {
			fmt.Println("乌龟到达终点",time.Now())
			waitFlag.Done()
			break
		}
	}
}

func main() {
	waitFlag.Add(2)

	runFlag.Add(1)

	var rabbit Rabbit
	rabbit.speed = 20
	rabbit.distance = 100
	rabbit.sleepCount = 20

	var tortoise Tortoise
	tortoise.speed = 10
	fmt.Println("比赛开始",time.Now())
	go rabbit.run()
	go tortoise.run()
	runFlag.Done()
	waitFlag.Wait()
}

func getDistance() int32 {
	var v int32
	lock.Lock()
	v = distance
	lock.Unlock()
	return v
}

func pullDistance(v int32){
	lock.Lock()
	atomic.AddInt32(&distance,v)

}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值