單任務隊列耗時
package main
import (
"crypto/rand"
"fmt"
"math/big"
"strconv"
"strings"
"sync"
"time"
)
type task struct {
id uint32 //
callback chan int
}
var chTask = make(chan task)
var wg sync.WaitGroup
var arr = [10]int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
func main() {
go working(chTask) // 就一個工廠開門(單任務隊列)
start := time.Now().UnixNano()
for i := 0; i < 100; i++ {
wg.Add(1) // 線程計數器+1
go order() // 給工廠派活
}
wg.Wait() // 等待所有任務處理完畢
fmt.Printf("所有任務已執行完畢,用時%v", time.Now().UnixNano()-start)
}
// 出任務的,甲方爸爸
func order() {
id := randomString(10) // 獲取訂單編號
callack := make(chan int) // 把返程的招呼打好
t := task{id: uint32(id), callback: callack} // 訂單起草完畢
chTask <- t // 把訂單交給小弟讓他送送工廠去
msg := <-callack // 拿到工廠編號
_ = msg
wg.Done() // 線程計數器-1
}
// 工廠,接收小弟(chan),返回工廠編號
func working(chTasks chan task) {
for {
t := <-chTasks // 卸貨
id := t.id // 訂單編號
//_ = id // 此處生產產品(業務邏輯)
for i := 0; i < 1000000; i++ {
_ = id
}
t.callback <- 1 // 返回工廠編號
}
}
// 生成訂單號
func randomString(n int) uint32 {
var b []string
for i := 0; i < n; i++ {
num, _ := rand.Int(rand.Reader, big.NewInt(int64(len(arr))))
// 1.將 *big.Int 轉化為 int64
// 2.將 int 64 轉化為 int
// 3.將 int 轉化為 string
b = append(b, strconv.Itoa(arr[int(num.Int64())]))
}
str := strings.Join(b, "") // 拼接字符串
a, _ := strconv.Atoi(str) // string 轉 int
yes := uint32(a) // int 轉 uint32
return yes
}
結果:所有任務已執行完畢,用時180531600
多任務隊列耗時
package main
import (
"crypto/rand"
"fmt"
"math/big"
"strconv"
"strings"
"sync"
"time"
)
type task struct {
id uint32 // 訂單編號
callback chan int // 工廠編號
}
const taskNum = 16 // 准備找16個工廠
var chTaskList = make([]chan task, taskNum) // 工廠列表
var wg sync.WaitGroup
var arr = [10]int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
func task_init() {
for i := 0; i < taskNum; i++ {
wg.Add(1)
chTaskList[i] = make(chan task) // 工廠登記
go working(chTaskList[i], i) // 工廠開門大吉,待命中
}
}
func main() {
// start := time.Now().UnixNano()
task_init() // 工廠就緒
wg.Wait() // 等待所有工廠就緒
start := time.Now().UnixNano()
for i := 0; i < 100; i++ {
wg.Add(1)
go order() // 給工廠派活
}
wg.Wait() // 等待所有任務處理完畢
fmt.Printf("所有任務已執行完畢,用時%v",time.Now().UnixNano() - start)
}
// 出任務的,甲方爸爸
func order() {
id := randomString(10) // 來個訂單號
callack := make(chan int) // 把返程的招呼打好
t := task{id: uint32(id), callback: callack} // 訂單起草完畢
chTasks := chTaskList[id%taskNum] // 隨機選擇一個工廠,因為id都是隨機生成的,取余數也是一個隨機值
chTasks <- t // 把訂單交給小弟讓他送送工廠去
msg := <-callack // 拿到工廠編號
_ = msg
//fmt.Printf("給%v號工廠下了訂單,%v號工廠拿到了訂單\n", id%taskNum, msg)
wg.Done()
}
// 工廠,接收小弟(chan),返回工廠編號
func working(chTasks chan task, num int) {
//fmt.Printf("第%v號工廠待命中...\n", num)
wg.Done()
for {
t := <-chTasks // 卸貨
id := t.id // 訂單編號
_ = id // 此處生產產品(業務邏輯)
t.callback <- num // 返回工廠編號
}
}
// 生成訂單號
func randomString(n int) uint32 {
var b []string
for i := 0; i < n; i++ {
num, _ := rand.Int(rand.Reader, big.NewInt(int64(len(arr))))
// 1.將 *big.Int 轉化為 int64
// 2.將 int 64 轉化為 int
// 3.將 int 轉化為 string
b = append(b, strconv.Itoa(arr[int(num.Int64())]))
}
str := strings.Join(b, "") // 拼接字符串
a, _ := strconv.Atoi(str) // string 轉 int
yes := uint32(a) // int 轉 uint32
return yes
}
結果:所有任務已執行完畢,用時3971800
測試機器是8核CPU
