GoLang 小练习:并发与通道,实现 员工、任务、机器 三者的安全配合!

package main

import (
	"fmt"
	"runtime"
	"time"
)

//任务分配:有n个员工 / n个任务 /n个机器,用高效,安全的方式完成自动分配执行
// 一个员工 只能使用 一台机器 来 完成一个任务

// 员工结构体
type Person struct {
	id int			//ID
	name string		//名称
	macid int		//当前操作的机器
	taskid int		//当前操作的任务
}

// 机器结构体
type Mac struct {
	id int			//ID
	name string		//名称
	status bool		//当前机器状态
}

//任务结构体
type Task struct {
	id int			//ID
	status int		//任务状态
	macid int		//完成任务机器
	perid int		//完成任务员工
}

// 员工列表
var personlist = []Person{
	{0,"员工0",-1,-1},
	{1,"员工1",-1,-1},
	{2,"员工2",-1,-1},
}
// 机器列表
var maclist = []Mac{{0,"机器0",false},{1,"机器1",false}}

// 任务列表
var tasklist = []Task{
	{0,-1,-1,-1},
	{1,-1,-1,-1},
	{2,-1,-1,-1},
	{3,-1,-1,-1},
	{4,-1,-1,-1},
	{5,-1,-1,-1},
}

// 机器管理员 接待
var MacAdminStatus = make(chan Person)
// 机器管理员 返回
var MacFunc = make(chan Mac)

// 任务管理员 接待
var TaskAdminStatus = make(chan Person)
// 任务管理员 返回
var TaskFunc = make(chan Task)


func main() {
	// 主管督促 所有员工干活
	for _,perit := range personlist{
		go person(perit)
	}
	// 机器管理小姐姐 上班啦
	go MacAdmin()
	// 任务管理小哥哥 上班啦
	go TaskAdmin()

	// 我是主管,在等待员工完成任务
	for{
		time.Sleep(time.Millisecond)
		istask := false
		for _,task := range tasklist{
			if task.status != 1{
				istask = true
				break
			}
		}
		if istask{
			continue
		}
		//任务结束了,可以下班了
		fmt.Println("任务结束了,可以下班了!")
		fmt.Println("")
		fmt.Println("----------------------------------------------------------")
		fmt.Printf("任务编号\t完成人\t完成机器\n")
		for _,item := range tasklist{
			//本次统计
			fmt.Printf("任务%d\t%s\t%s\n",item.id+1,personlist[item.perid].name,maclist[item.macid].name)
		}
		fmt.Println("----------------------------------------------------------")
		break
	}
}

//机器:主要作用是 被操控着 完成任务
func mac(info Mac,pinfo Person){
	fmt.Printf("%s 操控:%s开始执行\n",pinfo.name,info.name)
	//找到任务管理员 小哥哥 要一个任务
	fmt.Println(info.name,":问小哥哥要一个任务")
	TaskAdminStatus <- pinfo
	//接收要到的任务
	Task := <- TaskFunc
	if Task.id == -1{
		fmt.Println(info.name,":没有任务了,一会可能就下班了。")
		runtime.Goexit()
	}
	//开始执行任务
	fmt.Println(info.name,":开始执行任务")
	time.Sleep(time.Second * 5)
	//完成任务了
	fmt.Println(info.name,":完成",tasklist[personlist[pinfo.id].taskid].id,"任务了。")
	tasklist[personlist[pinfo.id].taskid].status = 1
	tasklist[personlist[pinfo.id].taskid].perid = pinfo.id
	tasklist[personlist[pinfo.id].taskid].macid = info.id

}

// 员工:主要作用是 通过机器完成任务
func person(info Person){
	for {
		fmt.Println(info.name,":开始执行")
		//问管理员要一台机器
		fmt.Println(info.name,":问小姐姐要一台机器")
		MacAdminStatus <- info
		Mac := <- MacFunc
		if Mac.id == -1{
			//还没有机器
			fmt.Println(info.name,":小姐姐没有机器了,等一下再来。")
			time.Sleep(time.Second)
			continue
		}
		//开始操控机器
		mac(Mac,info)
		//小姐姐有些忙 ,我直接放回仓库吧
		fmt.Println(info.name,":小姐姐有些忙 ,我直接放回仓库吧。")
		maclist[personlist[info.id].macid].status = false
		personlist[info.id].macid = -1
		//摸鱼是人类之本 休息 2秒
		time.Sleep(time.Second*2)
	}
}

//机器管理员小姐姐:主要作用是 分配机器
func MacAdmin(){
	for {
		// 这位同事 你好,需要什么服务?
		personitem := <-MacAdminStatus
		//找到一台空闲的机器
		ismac := false
		for inx,status := range maclist{
			if status.status == false {
				//找到了一台空闲的机器
				ismac = true
				maclist[inx].status = true
				personlist[personitem.id].macid = maclist[inx].id
				MacFunc <- status
				break
			}
		}
		// 成功找到了机器,等待下一个同事的到来
		if ismac{
			continue
		}
		// 没有找到机器,告诉同事一会再来
		MacFunc <- Mac{id:-1}
	}
}

//任务管理员小哥哥:主要作用是 分配任务
func TaskAdmin(){
	for {
		// 这位同事 你好,需要什么服务?
		personitem := <-TaskAdminStatus
		//找到一个任务
		istask := false
		for inx,status := range tasklist{
			if status.status == -1 {
				//找到了一个任务
				istask = true
				tasklist[inx].status = 0
				personlist[personitem.id].taskid = status.id
				TaskFunc <- status
				break
			}
		}
		// 成功找到了任务,等待下一个同事的到来
		if istask{
			continue
		}
		// 没有找到任务,告诉同事 还有一会就可以下班了
		TaskFunc <- Task{id:-1}
	}
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

rock__rabbit

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值