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

python使用協(xié)程實(shí)現(xiàn)并發(fā)操作的方法詳解

 更新時(shí)間:2019年12月27日 11:51:24   作者:雪山飛豬  
這篇文章主要介紹了python使用協(xié)程實(shí)現(xiàn)并發(fā)操作的方法,結(jié)合實(shí)例形式詳細(xì)分析了Python協(xié)程的原理及使用Gevent實(shí)現(xiàn)協(xié)程操作的相關(guān)技巧與操作注意事項(xiàng),需要的朋友可以參考下

本文實(shí)例講述了python使用協(xié)程實(shí)現(xiàn)并發(fā)操作的方法。分享給大家供大家參考,具體如下:

協(xié)程

協(xié)程是一種用戶態(tài)的輕量級(jí)線程,又稱微線程。

協(xié)程擁有自己的寄存器上下文和棧,調(diào)度切換時(shí),將寄存器上下文和棧保存到其他地方,在切回來(lái)的時(shí)候,恢復(fù)先前保存的寄存器上下文和棧。因此:協(xié)程能保留上一次調(diào)用時(shí)的狀態(tài)(即所有局部狀態(tài)的一個(gè)特定組合),每次過(guò)程重入時(shí),就相當(dāng)于進(jìn)入上一次調(diào)用的狀態(tài),換種說(shuō)法:進(jìn)入上一次離開時(shí)所處邏輯流的位置。

優(yōu)點(diǎn):

  1. 無(wú)需線程上下文切換的開銷
  2. 無(wú)需原子操作鎖定及同步的開銷
  3. 方便切換控制流,簡(jiǎn)化編程模型
  4. 高并發(fā)+高擴(kuò)展性+低成本:一個(gè)CPU支持上萬(wàn)的協(xié)程都不是問(wèn)題。所以很適合用于高并發(fā)處理。

所謂原子操作是指不會(huì)被線程調(diào)度機(jī)制打斷的操作;這種操作一旦開始,就一直運(yùn)行到結(jié)束,中間不會(huì)有任何 context switch (切換到另一個(gè)線程)。

原子操作可以是一個(gè)步驟,也可以是多個(gè)操作步驟,但是其順序是不可以被打亂,或者切割掉只執(zhí)行部分。視作整體是原子性的核心。

缺點(diǎn):

  1. 無(wú)法利用多核資源:協(xié)程的本質(zhì)是個(gè)單線程,它不能同時(shí)將 單個(gè)CPU 的多個(gè)核用上,協(xié)程需要和進(jìn)程配合才能運(yùn)行在多CPU上.當(dāng)然我們?nèi)粘K帉懙慕^大部分應(yīng)用都沒有這個(gè)必要,除非是cpu密集型應(yīng)用。
  2. 進(jìn)行阻塞(Blocking)操作(如IO時(shí))會(huì)阻塞掉整個(gè)程序

使用Gevent

gevent是python的一個(gè)并發(fā)框架,以微線程greenlet為核心,使用了epoll事件監(jiān)聽機(jī)制以及諸多其他優(yōu)化而變得高效.

  • 簡(jiǎn)單示例

gevent的sleep可以交出控制權(quán),當(dāng)我們?cè)谑芟抻诰W(wǎng)絡(luò)或IO的函數(shù)中使用gevent,這些函數(shù)會(huì)被協(xié)作式的調(diào)度, gevent的真正能力會(huì)得到發(fā)揮。Gevent處理了所有的細(xì)節(jié), 來(lái)保證你的網(wǎng)絡(luò)庫(kù)會(huì)在可能的時(shí)候,隱式交出greenlet上下文的執(zhí)行權(quán)。

import gevent
def foo():
  print('running in foo')
  gevent.sleep(0)
  print('com back from bar in to foo')
def bar():
  print('running in bar')
  gevent.sleep(0)
  print('com back from foo in to bar')
# 創(chuàng)建線程并行執(zhí)行程序
gevent.joinall([
  gevent.spawn(foo),
  gevent.spawn(bar),
])

執(zhí)行結(jié)果

running in foo
running in bar
com back from bar in to foo
com back from foo in to bar

  • 同步異步
import random
import gevent
def task(pid):
  gevent.sleep(random.randint(0, 2) * 0.001)
  print('Task %s done' % pid)
def synchronous():
  for i in range(1, 10):
    task(i)
def asynchronous():
  threads = [gevent.spawn(task, i) for i in range(10)]
  gevent.joinall(threads)
print('Synchronous:')
synchronous()
print('Asynchronous:')
asynchronous()

執(zhí)行輸出

Synchronous:
Task 1 done
Task 2 done
Task 3 done
Task 4 done
Task 5 done
Task 6 done
Task 7 done
Task 8 done
Task 9 done
Asynchronous:
Task 1 done
Task 4 done
Task 5 done
Task 9 done
Task 6 done
Task 0 done
Task 2 done
Task 3 done
Task 7 done
Task 8 done

  • 以子類的方法使用協(xié)程

可以子類化Greenlet類,重載它的_run方法,類似多線程和多進(jìn)程模塊

import gevent
from gevent import Greenlet
class Test(Greenlet):
  def __init__(self, message, n):
    Greenlet.__init__(self)
    self.message = message
    self.n = n
  def _run(self):
    print(self.message, 'start')
    gevent.sleep(self.n)
    print(self.message, 'end')
tests = [
  Test("hello", 3),
  Test("world", 2),
]
for test in tests:
  test.start() # 啟動(dòng)
for test in tests:
  test.join() # 等待執(zhí)行結(jié)束

  • 使用monkey patch修改系統(tǒng)標(biāo)準(zhǔn)庫(kù)(自動(dòng)切換協(xié)程)

當(dāng)一個(gè)greenlet遇到IO操作時(shí),比如訪問(wèn)網(wǎng)絡(luò),就自動(dòng)切換到其他的greenlet,等到IO操作完成,再在適當(dāng)?shù)臅r(shí)候切換回來(lái)繼續(xù)執(zhí)行。

由于IO操作非常耗時(shí),經(jīng)常使程序處于等待狀態(tài),有了gevent為我們自動(dòng)切換協(xié)程,就保證總有g(shù)reenlet在運(yùn)行,而不是等待IO。

由于切換是在IO操作時(shí)自動(dòng)完成,所以gevent需要修改Python自帶的一些標(biāo)準(zhǔn)庫(kù),這一過(guò)程在啟動(dòng)時(shí)通過(guò)monkey patch完成

import gevent
import requests
from gevent import monkey
monkey.patch_socket()
def task(url):
  r = requests.get(url)
  print('%s bytes received from %s' % (len(r.text), url))
gevent.joinall([
  gevent.spawn(task, 'https://www.baidu.com/'),
  gevent.spawn(task, 'https://www.qq.com/'),
  gevent.spawn(task, 'https://www.jd.com/'),
])

執(zhí)行輸出

2443 bytes received from https://www.baidu.com/
108315 bytes received from https://www.jd.com/
231873 bytes received from https://www.qq.com/

可以看出3個(gè)網(wǎng)絡(luò)操作是并發(fā)執(zhí)行的,而且結(jié)束順序不同

參考鏈接:http://hhkbp2.github.io/gevent-tutorial/

更多關(guān)于Python相關(guān)內(nèi)容感興趣的讀者可查看本站專題:《Python進(jìn)程與線程操作技巧總結(jié)》、《Python數(shù)據(jù)結(jié)構(gòu)與算法教程》、《Python函數(shù)使用技巧總結(jié)》、《Python字符串操作技巧匯總》、《Python入門與進(jìn)階經(jīng)典教程》、《Python+MySQL數(shù)據(jù)庫(kù)程序設(shè)計(jì)入門教程》及《Python常見數(shù)據(jù)庫(kù)操作技巧匯總

希望本文所述對(duì)大家Python程序設(shè)計(jì)有所幫助。

相關(guān)文章

  • 虛擬環(huán)境及venv和virtualenv的區(qū)別說(shuō)明

    虛擬環(huán)境及venv和virtualenv的區(qū)別說(shuō)明

    這篇文章主要介紹了虛擬環(huán)境及venv和virtualenv的區(qū)別說(shuō)明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2021-02-02
  • 使用python將請(qǐng)求的requests headers參數(shù)格式化方法

    使用python將請(qǐng)求的requests headers參數(shù)格式化方法

    今天小編就為大家分享一篇使用python將請(qǐng)求的requests headers參數(shù)格式化方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2019-01-01
  • Python字符串中查找子串小技巧

    Python字符串中查找子串小技巧

    這篇文章主要介紹了Python字符串中查找子串小技巧,,需要的朋友可以參考下
    2015-04-04
  • Python獲取與處理文件路徑/目錄路徑實(shí)例代碼

    Python獲取與處理文件路徑/目錄路徑實(shí)例代碼

    我們?cè)谟胮ython進(jìn)行數(shù)據(jù)處理時(shí)往往需要將文件中的數(shù)據(jù)取出來(lái)做一些處理,下面這篇文章主要給大家介紹了關(guān)于Python獲取與處理文件路徑/目錄路徑的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2023-04-04
  • 解決Python3 struct報(bào)錯(cuò)argument for 's' must be a bytes object

    解決Python3 struct報(bào)錯(cuò)argument for 's'&

    這篇文章主要為大家介紹了解決Python3 struct報(bào)錯(cuò)argument for 's' must be a bytes object方法詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-08-08
  • 多個(gè)python文件調(diào)用logging模塊報(bào)錯(cuò)誤

    多個(gè)python文件調(diào)用logging模塊報(bào)錯(cuò)誤

    這篇文章主要介紹了多個(gè)python文件調(diào)用logging模塊產(chǎn)生錯(cuò)誤,需要的朋友可以參考下
    2020-02-02
  • 簡(jiǎn)潔的十分鐘Python入門教程

    簡(jiǎn)潔的十分鐘Python入門教程

    這篇文章主要介紹了簡(jiǎn)潔的十分鐘Python入門教程,Python語(yǔ)言本身的簡(jiǎn)潔也使得網(wǎng)絡(luò)上各種Python快門入門教程有著很高的人氣,本文是國(guó)內(nèi)此類其中的一篇,需要的朋友可以參考下
    2015-04-04
  • python+os根據(jù)文件名自動(dòng)生成文本

    python+os根據(jù)文件名自動(dòng)生成文本

    這篇文章主要為大家詳細(xì)介紹了python+os根據(jù)文件名自動(dòng)生成文本,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-03-03
  • 基于Python繪制三種不同的中國(guó)結(jié)

    基于Python繪制三種不同的中國(guó)結(jié)

    馬上就要迎來(lái)新年了,就繪制了幾個(gè)中國(guó)結(jié),嘿嘿!本文為大家整理了三個(gè)繪制中國(guó)結(jié)的方法,文中的示例代碼講解詳細(xì),快跟隨小編一起動(dòng)手嘗試一下吧
    2023-01-01
  • Python爬蟲抓取論壇關(guān)鍵字過(guò)程解析

    Python爬蟲抓取論壇關(guān)鍵字過(guò)程解析

    這篇文章主要介紹了Python爬蟲抓取論壇關(guān)鍵字過(guò)程解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-10-10

最新評(píng)論