goroutine 有以下幾種方式被終止:
1。 當他完成了它的工作。
2。 因為不可恢復的錯誤, 它不能繼續工作
3。 當他被告知 需要終止工作。
我們可以簡單的使用前兩種方法, 因為這兩種方法隱含在你的演算法中, 但"取消工作" 又是怎樣工作的呢?
例如:這樣情況: 子goroutine 是否該繼續執行可能是以許多其他goroutine 狀態的認知為基礎的。
通常是 main goroutine 具有這種語境知識能夠告訴其子goroutine 終止。
下面看乙個 洩漏的例子/ (goroutine 沒有進行死亡處理的例子)
func main() )
go func()
}()return completed
} dowork(nil)
//也許這裡有其他操作需要執行
fmt.println("done.")}*/
/**分析: dowork 的goroutine 在整個生命週期中都保留在記憶體中;顯然不合理,傳入的是nil 應該是更早的結束這個goroutine 才對。
怎麼解決呢,使用 done channel
分析: dowork 的goroutine 在整個生命週期中都保留在記憶體中;顯然不合理,傳入的是nil 應該是更早的結束這個goroutine 才對。
怎麼解決呢,使用 done channel
func main(), strings
go func()
}}()
return terminated
} done := make(chan inte***ce{})
terminated := dowork(done, nil)
go func() ()
fmt.println("done.")
}//cancelling dowork goroutine...
//dowork exited.
//done.
*//**
分析: 儘管我們給我們的字串 channel 中傳遞了nil, 我們的goroutine仍然成功退出。 通過 1s 後 關閉dowork 中 goroutine 成功消除了我們的
goroutine 洩漏
分析: 儘管我們給我們的字串 channel 中傳遞了nil, 我們的goroutine仍然成功退出。 通過 1s 後 關閉dowork 中 goroutine 成功消除了我們的
goroutine 洩漏
這個例子 是: dowork 的 goroutine 從某個channel(作為引數傳進來) 中 for 讀取
下面這個例子: dowork 中的goroutine 向某個channel() 中寫入(for方式)資料
func main()
}()return randstream
} randstream := newrandstream()
fmt.println("3 random ints:")
for i:=1; i<=3; i++}//
//3 random ints:
//1: 5577006791947779410
//2: 8674665223082153551
//3: 6129484611666145821
*//**
解決方案: 像接收案例一樣,為生產者提供乙個通知他 退出 的 done channel:
問題: 在三次迭代後,我們的goroutine試圖將下乙個隨機數傳送到不需要的被讀取的 channel. 我們沒有告訴生產者它可以停止了。
解決方案: 像接收案例一樣,為生產者提供乙個通知他 退出 的 done channel:
func main())
}}()
return randstream
} done := make(chan inte***ce{})
randstream := newrandstream(done)
fmt.println(" 3 random ints:")
for i:=1; i<=3; i++
close(done)
//正在模擬進行的工作
time.sleep(1 * time.second)}*/
/**為了goroutine 不洩漏, 約定: 如果goroutine 負責建立 goroutine,他也負責 確保可以停止 goroutine
*/
為了goroutine 不洩漏, 約定: 如果goroutine 負責建立 goroutine,他也負責 確保可以停止 goroutine
or-channel / 復合 done channel希望將 多個 channel 合併為 乙個 done channel ;該channel 在 任何乙個元件channel 關閉時 ,都將關閉, 注意:元件中其他channel 可沒有關閉!!!
這種模式通過遞迴 和 goroutine 建立乙個復合 done chanenl .
func main())
or = func(channels ...
ordone := make(chan inte***ce{})
//建立goroutine 以便可以不受阻塞地等待我們 channel上的訊息
go func()
default :
select
}}()
return ordone
} //下面是使用or channel乙個例子
sig := func(after time.duration)
go func()()
return c
} start := time.now()
sig(2*time.hour),
sig(2*time.minute),
sig(1*time.second),
sig(5*time.second),
sig(10*time.second),
sig(1*time.hour),
sig(1*time.minute),
) fmt.printf("done after %v", time.since(start))
time.sleep(5*time.minute);
}
or 函式呼叫圖形分析:
分析: 在組成or channel 的 元件中有多個channel; 這些channel 需要不同時間才能關閉(1s 10s 1m 等等);但是現象是 1s後關閉的這個channel(sig(1*time.second)) 導致 or channel 關閉。
這種模式:在系統中的模組交匯處非常有用。
Go之簡單併發
func calculate id int 使用go來實現併發 func main time.sleep 1e9 2 等待程式執行結束,避免無輸出 上面 是最基礎的併發,使用time.sleep做超時等待,將上面的超時等待換成sync.waitgroup func main i wg.wait wa...
Go併發模式之 約束
約束 在編寫併發 的時候,有以下幾種不同的保證操作安全的方法。1。用於共享記憶體的同步原語 如sync.mutex 2.通過通訊來 共享記憶體來進行同步 如 channel 在併發處理中還有其他幾種情況也是隱式併發安全的 3。不會發生改變的資料 4。受到保護的資料 約束 特定約束,和 詞法約束 特定...
Go併發模式 設計模式之複製請求
複製請求 程式正在處理 使用者的http請求,或者檢索乙個資料塊。你可以將請求分發到多個處理程式 無論是 goroutine 程序,還是伺服器 其中乙個將比其他 處理程式返回更快,可以 立即返回結果。下面例子 在 單個程序中,使用多個goroutine 作為處理程式。goroutine 將隨機休眠一...