libco和tornado、協程和非同步的一些理解
看了些libco的實現,感覺和tornado差不多,基本的思想還是線上程被阻塞的時候能夠去做其他的事情,此時還是用epoll來排程掛起和恢復
從這點看協程依然是基於非同步的,且是純非同步的,只是協程框架提供了更好的語義表達,程式碼書寫更方便了,因此,協程的使用也是用在有一定的IO的服務中,純計算的服務用起來並不合適。這樣來看,協程和執行緒的使用場景不同,說協程是使用者態執行緒容易誤導人
libco和tornado比較,有以下特點:
1 python的多執行緒效率太低,所以tornado只能是多程序的,libco用c++實現,則是可以用於執行緒中的
2 libco實現了棧記憶體hook,引入了共享棧,優化了協程切換的記憶體拷貝;tornado基於python的記憶體管理,有gc的語言確實很方便,使用future機制
3 libco也hook了系統IO函式,這樣用於開發更方便;tornado則需要自己來維護和寫非同步過程,尤其是用第三方rpc客戶端的時候
4 libco的非同步排程器是每毫秒掃一次定時器組,定時器組是一個固定大小的陣列,陣列元素是個拉鍊,每個定時器放在和定時器組當前時間差值的位置,所以不能設定太大的超時時間,預設最大是一分鐘;tornado是以定時器的deadline(now+timeout)為key,將定時器組維護成了一個最小堆,非同步排程器每次獲取最小的定時器,以其deadline-now作為排程器的超時時間,等待排程器超時或者響應了事件之後再掃描定時器組執行
兩者類似,都是犧牲了平均延遲時間,增加qps;每個非同步過程(協程)佔用CPU時間不能太長,需要分片主動讓出cpu
libco的作用:
1 優化常用的非同步IO+多執行緒(多程序)的服務(服務要有下游IO),這類服務的執行緒在與下游IO的時候還是會有一段時間段的阻塞,也就是沒事幹;協程可以充分利用這段時間
2 方便對mc,redis等第三方訪問的非同步,不然自己要從客戶端原始碼中抽取也要費很大力氣,還得搞很多狀態維護
2017/06/02
看了一些協程的介紹文章,協程更多的是一種機制理念,描述為使用者態執行緒,和非同步的區別在於主動儲存當前棧上下文
但是最適合的使用場景仍然是在IO,所以最終的實現原理和非同步差不多
2017/06/05:
協程的另一種應用場景是類似python中的yield,也有其他語言的類似實現,不過這種方式對效能有什麼影響?
看到一個函式:pthread_attr_setstack ,這個函式可以實現對執行緒棧記憶體的hook,為什麼不使用這個方式來實現協程呢,libco目前的做法有什麼好處?