首先說結論吧,我的感受go的goroutine 和C# 的Task 類似,goroutine 和Task 能夠近似理解爲邏輯線程, 至於多個goroutine 或Task 對應操做系統幾個物理線程 是底層決定的,咱們能夠不用太關心;可是必定是多對多【這個咱們能夠簡單理解多對一, 一個或多個goroutine 或Task 對應底層一個物理線程】, 具體的blockingcollection能夠參考 https://blog.csdn.net/ma_jiang/article/details/54561684, go channel 能夠參考https://blog.csdn.net/ma_jiang/article/details/84497607多線程
channel 和BlockingCollection 能夠再多線程之間通訊,尤爲是在同步通訊 都是運用它們阻塞的特定來作了。好比常見的接力賽: 使用無緩衝的通道,在 goroutine 之間同步數據,來模擬接力比賽。在接力比賽裏,4 個跑步者圍繞賽道輪流跑。第二個、第三個和第四個跑步者要接到前一位跑步者的接力棒後才能起跑。比賽中最重要的部分是要傳遞接力棒,要求同步傳遞。在同步接力棒的時候,參與接力的兩個跑步者必須在同一時刻準備好交接。spa
go的代碼:操作系統
package main import ( "fmt" "sync" "time" ) // wg 用來等待程序結束 var wg sync.WaitGroup // main 是全部Go 程序的入口 func main() { // 建立一個無緩衝的通道 baton := make(chan int) // 爲最後一位跑步者將計數加1 wg.Add(1) // 第一位跑步者持有接力棒 go Runner(baton) // 開始比賽 baton <- 1 // 等待比賽結束 wg.Wait() } // Runner 模擬接力比賽中的一位跑步者 func Runner(baton chan int) { var newRunner int // 等待接力棒 runner := <-baton // 開始繞着跑道跑步 fmt.Printf("Runner %d Running With Baton\n", runner) // 建立下一位跑步者 if runner != 4 { newRunner = runner + 1 fmt.Printf("Runner %d To The Line\n", newRunner) go Runner(baton) } // 圍繞跑道跑 time.Sleep(100 * time.Millisecond) // 比賽結束了嗎? if runner == 4 { fmt.Printf("Runner %d Finished, Race Over\n", runner) wg.Done() return } // 將接力棒交給下一位跑步者 fmt.Printf("Runner %d Exchange With Runner %d\n", runner, newRunner) baton <- newRunner }
C#代碼:.net
using System; using System.Collections.Concurrent; using System.Threading; using System.Threading.Tasks; namespace demo { class Program { static void Main(string[] args) { // 建立一個無緩衝的通道 var baton =new BlockingCollection<int>(1); // 第一位跑步者持有接力棒 Task.Factory.StartNew(x => Runner((BlockingCollection<int>)x), baton); baton.Add(1); while(!baton.IsCompleted){ Thread.Sleep(1000); } Console.Read(); } static void Runner(BlockingCollection<int> baton){ int newRunner=0 ; // 等待接力棒 int runner=baton.Take(); // 開始繞着跑道跑步 Console.WriteLine($"Runner {runner} Running With Baton"); // 建立下一位跑步者 if (runner!=4){ newRunner=runner+1; Console.WriteLine($"Runner {runner} To The Line"); Task.Factory.StartNew(x=>Runner((BlockingCollection<int>)x),baton); } // 圍繞跑道跑 Thread.Sleep(100); // 比賽結束了嗎? if(runner==4){ Console.WriteLine($"Runner {runner} Finished, Race Over"); baton.CompleteAdding(); return; } Console.WriteLine($"Runner {runner} Exchange With Runner {newRunner}"); baton.Add(newRunner); } } }
運行結果:線程