成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Python 的 Generator 和 Go 的 Concurrency Pattern

開發 后端
Python 的 generator 和 Go 的 goroutine 都是常用的技法。沒看到有人分析其間關系,所以在此記錄一下。這兩個概念都是為了 producer-consumer 模式的編程方便發明的。

Python 的 generator 和 Go 的 goroutine 都是常用的技法。沒看到有人分析其間關系,所以在此記錄一下。

這兩個概念都是為了 producer-consumer 模式的編程方便發明的。Python 的 generator 和 iterator 以及 iterable objects 一脈相承。Go 出現比 Python 晚,解決同樣的編程便捷性問題,用 channel 和 goroutine 兩個概念。

[[399246]]

Go 的做法

Go 的做法比較容易理解,因為和教材里的概念一致:producer 和 consumer 各自是一個 goroutine,而一個 goroutine 是一種 green thread —— 自己放棄執行,讓其他 gorotine 有機會占用 CPU,而不依賴一個 preemption 機制(比如 OS kernel)來強制休眠當前 thread 以騰出 CPU 給其他 thread。

producer 把數據寫入一個 channel,consumer 從這個 channel 里讀。一個 channel 就是一個 blocking queue,可以有一個 buffer。讀可以通過 loop 語法。比如

 

  1. package main 
  2.  
  3. func producer(n int) chan int { 
  4.     ch := make(chan int
  5.     go func() { // This goroutine is the producer 
  6.         for i := 0; i < n; i++ { 
  7.             ch <- i 
  8.         } 
  9.         close(ch) 
  10.     }() 
  11.     return ch 
  12.  
  13. func main() { // the main goroutine is the consumer 
  14.     for i := range producer(5) { 
  15.         println(i) 
  16.     } 

請注意,上述寫法讓一個 Go 函數創建和返回一個 channel,同時這個 Go 函數啟動一個“發射后不管”的 producer goroutine —— 這是標準 Go 做法,不太符合 C/C++ 的習俗 —— (1)創建 channel(2)啟動 producer 和 consumer threads。這是因為 C/C++ 不支持 high-order functions,或者叫 functionals。具體請參見我的這個回答 什么是函數式編程思維? 這個 Go pattern 和 Python 習俗一致,因為這倆都是 functional programming languages。

Python 的做法

上述 Go 的 producer 非常接近 Python 的 generator 的寫法 —— 兩點區別,都是 Python 解釋器代勞的結果:

  • Python 用戶不需要創建和關閉 channel 了。
  • ch <- i 這一行可以用 yield i 來代替。

對應的 Python generator 如下

 

  1. from typing import Iterator 
  2.  
  3. def producer(n: int) -> Iterator[int]: 
  4.   for i in range(n): 
  5.     yield i 
  6.  
  7. for i in producer(5): 
  8.   print(i) 

比較

Python 的 producer 不是一個函數,因為里面沒有 return,而是一個 generator,因為里面有 yield。一個函數返回一個值。而一個 generator 返回一個 iterator。

Go 的 producer 是一個函數,返回一個 channel。Go 里沒有 generator 這樣的“新概念”。

上面 Python generator 里的代碼和 Go producer 里啟動的 goroutine 的代碼幾乎完全一樣,只是把 ch <- i 換成了 yield i。

那么 Python generator 返回的 iterator 到底是個啥呢?其實就是那個 Go channel,或者叫 blocking queue 的。從這個角度看,Python generator 又是一個函數了,返回一個 blocking queue。

Python 里最常用的 generator 莫過于 range —— 上例中也出現了。所以上例中,其實調用 range 的時候,已經創建了一個 Python thread 往 range 返回的 blocking queue 里寫數字。而 producer 只是從這個 queue 里取出數字,再 yield 到 producer 創建的第二個 queue 里,讓 for i in producer(5) 這一行(由 main thread 執行)去讀。

這樣一串三個 Python threads,通過兩個 queues 連成一串,就是 Rob Pike 在著名幻燈片 https://talks.golang.org/2012/concurrency.slide#1 里展示 Go concurrency pattern 里的 pipeline:

不過這里有一個區別,goroutines 是可以并行執行的,如果我們電腦里有多個 CPU cores。不過,Python threads 雖然就是 OS thread 卻受制于 Python 的 GIL,所以任何時候只有一個 Python 在執行中,即使我們有很多 CPU cores。請看https://www.zhihu.com/pin/1343421894465474560

Occam's Razor

我們設計系統的時候經常需要遵循一個哲學原則 Occam's Razor —— 能達到目的的各種手段里我們選擇最簡單的那個。這也是本專欄名字的由來。在漢語里,這個原則(philosophical principle)叫“刪繁就簡三秋樹”。如果做不到,必然積累還不完的技術債,以至于不可能“領異標新二月花”。

對比上面 Go 和 Python 兩個例子,顯然 Python 例子的代碼更簡單。那么是不是就說明 Python 語言的設計比 Go 更加符合 Occam's Razor 的原則了呢?

恐怕并不盡然。雖然 Python 代碼簡短,但是需要用戶理解更多概念(generator,iterator,以及它們和 functions 以及 queues 的潛在關系)—— 這也是一種開銷。

這里只是提醒大家關注保持設計的簡潔。不在于挖坑比較 Python 和 Go 語言。如果回復有涉及這樣比較的,恕刪。:-)

責任編輯:未麗燕 來源: 知乎
相關推薦

2020-08-12 08:51:19

Go語言Concurrency后臺

2017-07-28 10:05:58

Pythonyieldgenerator

2021-03-16 16:16:41

GeneratorWebsockets前端

2013-08-20 13:22:35

PythonGo編程語言

2009-06-29 08:59:05

hbm的generat

2022-02-09 16:02:26

Go 語言ArraySlice

2022-06-02 13:54:04

Go數組切片

2024-12-13 08:02:10

PythonGenerator懶加載

2009-06-29 08:58:06

Hibernate的g

2018-04-19 14:54:12

2023-03-29 08:03:53

2018-07-30 13:29:04

WebAssemblyGo語言

2009-07-02 09:32:47

generator子元Hibernate

2021-10-18 09:08:27

Go分段棧連續棧

2023-12-30 18:35:37

Go識別應用程序

2023-11-21 15:46:13

Go內存泄漏

2012-06-15 09:56:40

2023-10-23 19:27:21

Go函數

2025-05-20 08:20:00

GoGo Context上下文

2023-06-10 23:01:41

GrpcProtobuf數據
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 久视频在线 | 中文福利视频 | 手机三级电影 | 91精品国产综合久久久动漫日韩 | 毛片网在线观看 | 在线观看视频一区二区三区 | 亚洲人成网亚洲欧洲无码 | 在线免费观看a级片 | 日韩欧美三区 | 亚洲精品播放 | 妞干网福利视频 | 久久久久久中文字幕 | 天天艹逼网 | 精精久久 | 久久蜜桃资源一区二区老牛 | 97色综合| 黑人巨大精品欧美一区二区一视频 | 综合一区二区三区 | 国产成人精品久久二区二区91 | 国产片一区二区三区 | 日韩高清一区 | 亚洲黄色一级毛片 | 91精品入口蜜桃 | 第一色在线 | 91在线成人| 国产日韩欧美一区二区在线播放 | 久久精品com | 国产一区二区在线播放视频 | 一区二区三区欧美在线观看 | 一起操网站 | 黄a在线观看 | 男女精品久久 | 欧美日韩在线综合 | 欧美精品一区二区在线观看 | 日本久久一区 | 精品福利在线 | 久久精品欧美一区二区三区不卡 | 成人啊啊啊 | 在线观看国产视频 | 欧美午夜精品久久久久久浪潮 | 国产一区二区激情视频 |