go goroutine channel 和C# Task BlockingCollection

首先說結論吧,我的感受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);

        }
    }
}

運行結果:線程

相關文章
相關標籤/搜索