<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??一站式輕松地調用各大LLM模型接口,支持GPT4、智譜、豆包、星火、月之暗面及文生圖、文生視頻 廣告
                ## 什么是協程   協程,又稱微線程,纖程。英文名Coroutine。**協程是一種用戶態的輕量級線程**。協程擁有自己的寄存器上下文和棧。協程調度切換時,將寄存器上下文和棧保存到其他地方,在切回來的時候,恢復先前保存的寄存器上下文和棧。因此:協程能保留上一次調用時的狀態,每次過程重入時,就相當于進入上一次調用的狀態,換種說法:進入上一次離開時所處邏輯流的位置。 ### 協程優點 * 無需線程上下文切換的開銷 * 無需原子操作鎖定及同步的開銷 * 方便切換控制流,簡化編程模型 * 高并發+高擴展性+低成本:一個CPU支持上萬的協程都不是問題。所以很適合用于高并發處理。 PS: "原子操作(atomic operation)是不需要synchronized",所謂原子操作是指不會被線程調度機制打斷的操作;這種操作一旦開始,就一直運行到結束,中間不會有任何 context switch (切換到另一個線程)。原子操作可以是一個步驟,也可以是多個操作步驟,但是其順序是不可以被打亂,或者切割掉只執行部分。視作整體是原子性的核心。 ### 協程缺點 * 無法利用多核資源:協程的本質是個單線程,它不能同時將 單個CPU 的多個核用上,協程需要和進程配合才能運行在多CPU上.當然我們日常所編寫的絕大部分應用都沒有這個必要,除非是cpu密集型應用。 * 進行阻塞(Blocking)操作(如IO時)會阻塞掉整個程序 ## 協程引入   之前我們有用過yield關鍵字將用過函數變成一個生成器,實現了在單線程情況下的并發效果,如下例所示: ``` import time import queue def consumer(name): print("--->starting eating baozi...") while True: new_baozi = yield print("[%s] is eating baozi %s" % (name,new_baozi)) time.sleep(1) def producer(): r = con.__next__() r = con2.__next__() n = 0 while n < 5: n +=1 con.send(n) con2.send(n) print("\033[32;1m[producer]\033[0m is making baozi %s" %n ) if __name__ == '__main__': con = consumer("c1") con2 = consumer("c2") p = producer() ```   那么這算不算協程呢?我們先要知道到底滿足什么條件才算是一個協程。 1. **必須在只有一個單線程里實現并發** 2. **修改共享數據不需加鎖** 3. **用戶程序里自己保存多個控制流的上下文棧** 4. **一個協程遇到IO操作自動切換到其它協程**   如果滿足了以上的條件我們就可以認為是一個協程。所以yield并完全算是一個協程,因為它不能實現遇到IO操作就自動切換到其他協程的功能。 ## Greenlet   greenlet是一個用C實現的協程模塊,相比與python自帶的yield,它可以使你在任意函數之間隨意切換,而不需把這個函數先聲明為generator。 ~~~ from greenlet import greenlet def test1(): print(12) gr2.switch() print(34) gr2.switch() def test2(): print(56) gr1.switch() print(78) gr1 = greenlet(test1) gr2 = greenlet(test2) gr1.switch() 執行結果: 12 56 34 78 ~~~ 但是這個模塊沒有解決一個問題,就是自動切換IO操作,上面的切換是我們人為手動切換的。 ## Gevent Gevent 是一個第三方庫,可以輕松通過gevent實現并發同步或異步編程,在gevent中用到的主要模式是**Greenlet**, 它是以C擴展模塊形式接入Python的輕量級協程。 Greenlet全部運行在主程序操作系統進程的內部,但它們被協作式地調度。 ~~~ import gevent def func1(): print('\033[31;1m我是func1的1\033[0m') gevent.sleep(2) print('\033[31;1m我是func1的2\033[0m') def func2(): print('\033[32;1m我是func2的1\033[0m') gevent.sleep(1) print('\033[32;1m我是func2的2\033[0m') def func3(): print('\033[32;1m我是func3的1\033[0m') gevent.sleep(0) print('\033[32;1m我是func3的2\033[0m') gevent.joinall([ gevent.spawn(func1), gevent.spawn(func2), gevent.spawn(func3), ]) 輸出結果: 我是func1的1 我是func2的1 我是func3的1 我是func3的2 我是func2的2 我是func1的2 ~~~
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看