1. 程式人生 > >協程 和 async await

協程 和 async await

匯編 wait 包含 高級 地址 階段 方式 技術含量 編譯

協程, 是 為了 避免 閉包傳遞變量 的 性能損耗 而產生 。

如果不是 為了 避免 閉包傳遞變量 的 性能損耗 , 線程池 和 Task 已經夠了, 不需要 再設計 出 協程 來 。

閉包, 會 讓 所有共享 的 變量 變成 引用 訪問 的 方式,包括 值變量 。

因為 閉包 是將 變量 放到 堆 裏 共享 。

協程 就是在 堆 裏 模擬出一個 堆棧 和 協程“上下文” 存儲區, 這和 操作系統 的 線程 堆棧 和 上下文 架構 是 相似 的 。

上下文存儲區 保存 每個 協程 的 堆棧 的 棧頂 棧底, 在 切換 協程 時, 將 棧頂 棧底 存入 CPU 寄存器,

這樣, 代碼 中 對 變量 的 訪問 就可以 和 線程 一樣, 通過 編譯在 指令中 的 偏移量 操作數 加上 棧底 的 地址 就可以得到 變量 的 地址 。

這樣 對 函數 局部變量 的 訪問 就和 線程 一樣 , 指令 偏移量 操作數 + 棧底 , 這樣 一次 尋址 。

避免了 閉包 將 變量 變成 引用訪問 的 二次尋址 帶來 的 性能損耗 。

所以, C# 的 async await 本身 就 包含了 一個 協程 的 實現, 這大概也是 C# async await 要通過 編譯器 把 代碼 編譯為 狀態機 而不是 Task.ContinueWith() 的 原因 。

協程 需要 編譯器 在 匯編 層面 實現, 不能 通過 高級語言 的 類庫 / 封裝 / 設計模式 的 方式實現 。

InnerC 還不能 描述 協程, 可以考慮 給 InnerC 增加 協程 的 語法支持 。

在 現階段, 協程 是一個 有 技術含量 和 競爭力 的 技術 。

協程 和 async await