背景
后臺(tái)廣告系統(tǒng)匹配由串行轉(zhuǎn)為并行,涉及到并發(fā)數(shù)控制和一些資源回收工作,利用channel去做非常容易實(shí)現(xiàn)。細(xì)節(jié)是魔鬼,還是寫的少:)
有問(wèn)題代碼示例

代碼實(shí)現(xiàn)功能很簡(jiǎn)單,for 循環(huán)中接收 N 個(gè) channel 的數(shù)據(jù),業(yè)務(wù) channel 傳送業(yè)務(wù)數(shù)據(jù),最后一個(gè) ch 用來(lái)傳遞取消信號(hào),如果 ch 接收到數(shù)據(jù)那么退出 for 循環(huán)。按照 C-LIKE 習(xí)慣,理想的輸出肯定這樣的:
start cancel
do something?
do something
do something
receive cancel 0
over
但是真實(shí)情況是:
start cancel
do something
do something
do something
receive cancel :0receive cancel :0 無(wú)數(shù)個(gè) receive cancel :0陷入死循環(huán)?
channel 特性
先拋開(kāi)問(wèn)題,簡(jiǎn)單列一個(gè) channel 的特性
1. buffered channel 和 unbuffered channel,緩沖與否的區(qū)別
2. 寫入關(guān)閉的 channel 會(huì)導(dǎo)致panic
3. 數(shù)據(jù)未消費(fèi)完的 buffered channel 關(guān)閉后,是可以讀到未消費(fèi)數(shù)據(jù)
4. 無(wú)數(shù)據(jù)的 channel 關(guān)閉后,可以立刻讀到該類型的零值
死循環(huán)原因
上面列的 channel 特性只是為了湊數(shù) ~~
Golang 中的 break 有兩種寫法,一個(gè)是 break, 一個(gè)是 break [label], 見(jiàn)官方文檔,經(jīng)過(guò)測(cè)試有如下結(jié)論:
1. 不帶 label 的break,只能退出最近的 loop,并且對(duì) select, switch 無(wú)效
2. 帶 label 的 break,對(duì) for, select , switch 均有效
3. break 的 label 只能附著在同一函數(shù)的 for, select 或 switch 語(yǔ)句上,對(duì)比來(lái)講 goto 的 label就隨意一些
退出的正確姿勢(shì)

或是用 C-Like 的goto
