欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Python greenlet實現(xiàn)原理和使用示例

 更新時間:2014年09月24日 11:00:11   投稿:junjie  
這篇文章主要介紹了Python greenlet實現(xiàn)原理和使用示例,greenlet是Python中的一個并行處理庫,需要的朋友可以參考下

最近開始研究Python的并行開發(fā)技術,包括多線程,多進程,協(xié)程等。逐步整理了網(wǎng)上的一些資料,今天整理了一下greenlet相關的資料。

并發(fā)處理的技術背景

并行化處理目前很受重視, 因為在很多時候,并行計算能大大的提高系統(tǒng)吞吐量,尤其在現(xiàn)在多核多處理器的時代, 所以像lisp這種古老的語言又被人們重新拿了起來, 函數(shù)式編程也越來越流行。 介紹一個python的并行處理的一個庫: greenlet。 python 有一個非常有名的庫叫做 stackless ,用來做并發(fā)處理, 主要是弄了個叫做tasklet的微線程的東西, 而greenlet 跟stackless的最大區(qū)別是, 他很輕量級?不夠, 最大的區(qū)別是greenlet需要你自己來處理線程切換, 就是說,你需要自己指定現(xiàn)在執(zhí)行哪個greenlet再執(zhí)行哪個greenlet。

greenlet的實現(xiàn)機制

以前使用python開發(fā)web程序,一直使用的是fastcgi模式.然后每個進程中啟動多個線程來進行請求處理.這里有一個問題就是需要保證每個請求響應時間都要特別短,不然只要多請求幾次慢的就會讓服務器拒絕服務,因為沒有線程能夠響應請求了.平時我們的服務上線都會進行性能測試的,所以正常情況沒有太大問題.但是不可能所有場景都測試到.一旦出現(xiàn)就會讓用戶等好久沒有響應.部分不可用導致全部不可用.后來轉換到了coroutine,python 下的greenlet.所以對它的實現(xiàn)機制做了一個簡單的了解.

每個greenlet都只是heap中的一個python object(PyGreenlet).所以對于一個進程你創(chuàng)建百萬甚至千萬個greenlet都沒有問題.

復制代碼 代碼如下:

typedef struct _greenlet {
 PyObject_HEAD
 char* stack_start;
 char* stack_stop;
 char* stack_copy;
 intptr_t stack_saved;
 struct _greenlet* stack_prev;
 struct _greenlet* parent;
 PyObject* run_info;
 struct _frame* top_frame;
 int recursion_depth;
 PyObject* weakreflist;
 PyObject* exc_type;
 PyObject* exc_value;
 PyObject* exc_traceback;
 PyObject* dict;
} PyGreenlet;

每一個greenlet其實就是一個函數(shù),以及保存這個函數(shù)執(zhí)行時的上下文.對于函數(shù)來說上下文也就是其stack..同一個進程的所有的greenlets共用一個共同的操作系統(tǒng)分配的用戶棧.所以同一時刻只能有棧數(shù)據(jù)不沖突的greenlet使用這個全局的棧.greenlet是通過stack_stop,stack_start來保存其stack的棧底和棧頂?shù)?如果出現(xiàn)將要執(zhí)行的greenlet的stack_stop和目前棧中的greenlet重疊的情況,就要把這些重疊的greenlet的棧中數(shù)據(jù)臨時保存到heap中.保存的位置通過stack_copy和stack_saved來記錄,以便恢復的時候從heap中拷貝回棧中stack_stop和stack_start的位置.不然就會出現(xiàn)其棧數(shù)據(jù)會被破壞的情況.所以應用程序創(chuàng)建的這些greenlet就是通過不斷的拷貝數(shù)據(jù)到heap中或者從heap中拷貝到棧中來實現(xiàn)并發(fā)的.對于io型的應用程序使用coroutine真的非常舒服.

下面是greenlet的一個簡單的??臻g模型(from greenlet.c)

復制代碼 代碼如下:

A PyGreenlet is a range of C stack addresses that must be
saved and restored in such a way that the full range of the
stack contains valid data when we switch to it.

Stack layout for a greenlet:

               |     ^^^       |
               |  older data   |
               |               |
  stack_stop . |_______________|
        .      |               |
        .      | greenlet data |
        .      |   in stack    |
        .    * |_______________| . .  _____________  stack_copy + stack_saved
        .      |               |     |             |
        .      |     data      |     |greenlet data|
        .      |   unrelated   |     |    saved    |
        .      |      to       |     |   in heap   |
 stack_start . |     this      | . . |_____________| stack_copy
               |   greenlet    |
               |               |
               |  newer data   |
               |     vvv       |

下面是一段簡單的greenlet代碼.

復制代碼 代碼如下:

from greenlet import greenlet

def test1():
    print 12
    gr2.switch()
    print 34

def test2():
    print 56
    gr1.switch()
    print 78

gr1 = greenlet(test1)
gr2 = greenlet(test2)
gr1.switch()

目前所討論的協(xié)程,一般是編程語言提供支持的。目前我所知提供協(xié)程支持的語言包括python,lua,go,erlang, scala和rust。協(xié)程不同于線程的地方在于協(xié)程不是操作系統(tǒng)進行切換,而是由程序員編碼進行切換的,也就是說切換是由程序員控制的,這樣就沒有了線程所謂的安全問題。

所有的協(xié)程都共享整個進程的上下文,這樣協(xié)程間的交換也非常方便。

相對于第二種方案(I/O多路復用),使得使用協(xié)程寫的程序將更加的直觀,而不是將一個完整的流程拆分成多個管理的事件處理。協(xié)程的缺點可能是無法利用多核優(yōu)勢,不過,這個可以通過協(xié)程+進程的方式來解決。

協(xié)程可以用來處理并發(fā)來提高性能,也可以用來實現(xiàn)狀態(tài)機來簡化編程。我用的更多的是第二個。去年年底接觸python,了解到了python的協(xié)程概念,后來通過pycon china2011接觸到處理yield,greenlet也是一個協(xié)程方案,而且在我看來是更可用的一個方案,特別是用來處理狀態(tài)機。

目前這一塊已經(jīng)基本完成,后面抽時間總結一下。

總結一下:

1)多進程能夠利用多核優(yōu)勢,但是進程間通信比較麻煩,另外,進程數(shù)目的增加會使性能下降,進程切換的成本較高。程序流程復雜度相對I/O多路復用要低。

2)I/O多路復用是在一個進程內部處理多個邏輯流程,不用進行進程切換,性能較高,另外流程間共享信息簡單。但是無法利用多核優(yōu)勢,另外,程序流程被事件處理切割成一個個小塊,程序比較復雜,難于理解。

3)線程運行在一個進程內部,由操作系統(tǒng)調度,切換成本較低,另外,他們共享進程的虛擬地址空間,線程間共享信息簡單。但是線程安全問題導致線程學習曲線陡峭,而且易出錯。

4)協(xié)程有編程語言提供,由程序員控制進行切換,所以沒有線程安全問題,可以用來處理狀態(tài)機,并發(fā)請求等。但是無法利用多核優(yōu)勢。

上面的四種方案可以配合使用,我比較看好的是進程+協(xié)程的模式。

相關文章

  • pip安裝python庫的方法總結

    pip安裝python庫的方法總結

    在本篇文章里小編給大家分享了關于使用pip安裝python庫的幾種常用方法,有需要的朋友們可以參考下。
    2019-08-08
  • Python中使用socket發(fā)送HTTP請求數(shù)據(jù)接收不完整問題解決方法

    Python中使用socket發(fā)送HTTP請求數(shù)據(jù)接收不完整問題解決方法

    這篇文章主要介紹了Python中使用socket發(fā)送HTTP請求數(shù)據(jù)接收不完整問題解決方法,本文使用一個循環(huán)解決了數(shù)據(jù)不完整問題,需要的朋友可以參考下
    2015-02-02
  • 淺談pycharm使用及設置方法

    淺談pycharm使用及設置方法

    這篇文章主要介紹了淺談pycharm使用及設置方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2019-09-09
  • 微信跳一跳游戲python腳本

    微信跳一跳游戲python腳本

    這篇文章主要為大家詳細介紹了微信跳一跳游戲python腳本,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-01-01
  • python采用django框架實現(xiàn)支付寶即時到帳接口

    python采用django框架實現(xiàn)支付寶即時到帳接口

    這篇文章主要介紹了python采用django框架實現(xiàn)支付寶即時到帳接口的相關資料,需要的朋友可以參考下
    2016-05-05
  • Pycharm之如何安裝cv2 [python3.6]

    Pycharm之如何安裝cv2 [python3.6]

    這篇文章主要介紹了Pycharm之如何安裝cv2 [python3.6]問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-05-05
  • Python實現(xiàn)的RSS閱讀器實例

    Python實現(xiàn)的RSS閱讀器實例

    這篇文章主要介紹了Python實現(xiàn)的RSS閱讀器,實例分析了XML解析實現(xiàn)RSS閱讀的相關技巧,具有一定參考借鑒價值,需要的朋友可以參考下
    2015-07-07
  • 人工智能最火編程語言 Python大戰(zhàn)Java!

    人工智能最火編程語言 Python大戰(zhàn)Java!

    開發(fā)者到底應該學習哪種編程語言才能獲得機器學習或數(shù)據(jù)科學這類工作呢?這是一個非常重要的問題。本文為大家提供作者的答案并解釋原因
    2017-11-11
  • python opencv將表格圖片按照表格框線分割和識別

    python opencv將表格圖片按照表格框線分割和識別

    這篇文章主要介紹了python opencv將表格圖片按照表格框線分割和識別,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2019-10-10
  • Django model重寫save方法及update踩坑詳解

    Django model重寫save方法及update踩坑詳解

    這篇文章主要介紹了Django model重寫save方法及update踩坑詳解,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-07-07

最新評論