亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定

初學go,求指教

自己實現了一個,然后看了下老師的視頻,發現實現方式完全不一樣。

不知道老師有沒時間看下我這個例子,指導下有啥優缺點。

另外看完了老師關于goroutine的系列課程,收獲很多,感謝感謝

package main


import (

"fmt"

"time"

"sync"

)


//材料結構體

type data struct {

uid int //區分每個材料,便于打印展示

id int //區分每種材料,便于打印展示

time int //清洗耗時

}


var wg sync.WaitGroup


//每種材料個數

// var count int = rand.Intn(10) + 1

var count int = 5

var chanA = make(chan data, count*3)

var chanB = make(chan data, count)

var chanC = make(chan data, count)


//獲取當前毫秒級時間

func now() int64 {

return (int64)(time.Now().UnixNano() / 1000 / 1000)

}


//清理材料

func A(id int) {

for {

select {

case d := <- chanA :?

fmt.Printf("time:%d A車工人:%d,材料%d:%d 清洗中...\n", now(), id, d.id, d.uid)

time.Sleep((time.Duration)(d.time * 100) * time.Millisecond)

fmt.Printf("time:%d A車工人:%d,材料%d:%d 清洗完成\n", now(), id, d.id, d.uid)

//清理完成,放入加工管道

chanB <- d

default :

break

}

}

}


//加工材料

func B(id int) {

cnt := 0

for {

select {

case d := <- chanB :?

fmt.Printf("time:%d B車工人:%d,材料%d:%d 加工中...\n", now(), id, d.id, d.uid)

time.Sleep(100 * time.Millisecond)

fmt.Printf("time:%d B車工人:%d,材料%d:%d 加工完成\n", now(), id, d.id, d.uid)

//加工完成,放入裝載管道

chanC <- d

cnt += 1

default :

}


if cnt >= count {

break

}

}

}


//裝載材料

func C(id int) {

for {

select {

case d := <- chanC :?

fmt.Printf("time:%d C車工人:%d,材料%d:%d 裝載中...\n", now(), id, d.id, d.uid)

time.Sleep(100 * time.Millisecond)

fmt.Printf("time:%d C車工人:%d,材料%d:%d 裝載完成\n", now(), id, d.id, d.uid)

//清理完成,放入裝載管道

wg.Done()

default :

}

}

}


func main() {

fmt.Println("demo start")

//聲明3種材料需要的空間

var list []data = make([]data, count*3)

var d data

//填充3種材料的數據

for i := 0; i < count; i++ {

//填充第一種材料數據,清洗耗時6

d = data{uid : i, id : 1, time : 6}

list[i] = d

//填充第二種材料數據,清洗耗時3

d = data{uid : i, id : 2, time : 3}

list[i + count] = d

//填充第二種材料數據,清洗耗時3

d = data{uid : i, id : 3, time : 3}

list[i + count * 2] = d

}


//往清洗的管道按清洗時間長短填充

for i := 0; i < len(list); i++ {

chanA <- list[i]

}


//A車3個清洗工人

go A(1)

go A(2)

go A(3)


//B車3個加工工人

go B(1)

go B(2)

go B(3)


//C車3個裝載工人

go C(1)

go C(2)

go C(3)


wg.Add(count*3)


wg.Wait()


fmt.Println("demo end")

}


正在回答

1 回答

package?main

import?(
???"fmt"
???"sync"
???"time"
)

var?global?=?sync.WaitGroup{}

//?A車傳送給B車的通道
var?ch1?=?make(chan?*material,?3)

//?B車傳送給C車的通道
var?ch2?=?make(chan?*material,?3)

//?食材
type?material?struct?{
???//?食材名稱
???name?string
???//?食材數量
???count?byte
???//?A車處理所需花費時間,單位秒
???elapsedTimeA?uint
???//?B車處理所需花費時間,單位秒
???elapsedTimeB?uint
???//?C車處理所需花費時間,單位秒
???elapsedTimeC?uint
}

func?main()?{
???global.Add(3)
???//?所有需要處理的食材
???materials?:=?[]*material{
??????{"白菜",?12,?2,?1,?1},
??????{"青菜",?12,?1,?1,?1},
??????{"胡蘿卜",?12,?1,?1,?1},
???}
???start?:=?time.Now()
???go?A(materials)
???go?B()
???go?C()
???global.Wait()
???cost?:=?time.Since(start)
???fmt.Printf("總耗時:%s\n",?cost)
}
func?A(materials?[]*material)?{
???fmt.Printf("A車出發\n")
???//?循環處理每種食材
???for?_,?ele?:=?range?materials?{
??????var?worker?=?sync.WaitGroup{}
??????worker.Add(3)
??????//?3名工人分別處理每種食材的1/3
??????for?i?:=?0;?i?<?3;?i++?{
?????????go?func(index?int,?ele2?*material)?{
????????????fmt.Printf("A車工人[%d]正在清洗食材[%s],數量[%d],預計耗時[%d]秒\n",?index,?ele2.name,?ele2.count/3,?ele2.elapsedTimeA)
????????????//?睡眠模擬處理食材耗時
????????????time.Sleep(time.Second?*?time.Duration(ele2.elapsedTimeA))
????????????worker.Done()
?????????}(i,?ele)
??????}
??????//?等待所有工人都處理完畢后,把處理后的食材傳送給B車
??????worker.Wait()
??????fmt.Printf("A車食材[%s]正在運往B車\n",?ele.name)
??????ch1?<-?ele
???}
???fmt.Printf("A車任務結束\n")
???global.Done()
}

func?B()?{
???fmt.Printf("B車出發\n")
???//?循環處理3種食材
???for?i?:=?0;?i?<?3;?i++?{
??????//?從通道取不到數據時會阻塞,只有通道關閉時ok才等于false,所以下面的if判斷可以忽略
??????ele,?ok?:=?<-ch1
??????if?!ok?{
?????????break
??????}
??????fmt.Printf("B車接收到A車食材[%s]\n",?ele.name)
??????var?worker?=?sync.WaitGroup{}
??????worker.Add(3)
??????for?j?:=?0;?j?<?3;?j++?{
?????????go?func(index?int,?ele2?*material)?{
????????????fmt.Printf("B車工人[%d]正在加工食材[%s],數量[%d],預計耗時[%d]秒\n",?index,?ele2.name,?ele2.count/3,?ele2.elapsedTimeB)
????????????//?睡眠模擬處理食材耗時
????????????time.Sleep(time.Second?*?time.Duration(ele2.elapsedTimeB))
????????????worker.Done()
?????????}(j,?ele)
??????}
??????//?等待所有工人都處理完畢后,把處理后的食材傳送給C車
??????worker.Wait()
??????fmt.Printf("B車食材[%s]正在運往C車\n",?ele.name)
??????ch2?<-?ele
???}
???fmt.Printf("B車任務結束\n")
???global.Done()
}

func?C()?{
???fmt.Printf("C車出發\n")
???for?i?:=?0;?i?<?3;?i++?{
??????//?從通道取不到數據時會阻塞,只有通道關閉時ok才等于false,所以下面的if判斷可以忽略
??????ele,?ok?:=?<-ch2
??????if?!ok?{
?????????break
??????}
??????fmt.Printf("C車接收到B車食材[%s]\n",?ele.name)
??????var?worker?=?sync.WaitGroup{}
??????worker.Add(3)
??????for?j?:=?0;?j?<?3;?j++?{
?????????go?func(index?int,?ele2?*material)?{
????????????fmt.Printf("C車工人[%d]正在裝載食材[%s],數量[%d],預計耗時[%d]秒\n",?index,?ele2.name,?ele2.count/3,?ele2.elapsedTimeC)
????????????//?睡眠模擬處理食材耗時
????????????time.Sleep(time.Second?*?time.Duration(ele2.elapsedTimeC))
????????????worker.Done()
?????????}(j,?ele)
??????}
??????worker.Wait()
???}
???fmt.Printf("C車任務結束\n")
???global.Done()
}


0 回復 有任何疑惑可以回復我~

舉報

0/150
提交
取消
Go并發之魂:Goroutine深入淺出【程序人生中的“米其林三星級”并發實戰】
  • 參與學習       5547    人
  • 解答問題       8    個

深入淺出Go并發核心:Goroutine,斬獲Goroutine面試題。

進入課程

初學go,求指教

我要回答 關注問題
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號