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

如何在Python中編寫并發(fā)程序

 更新時間:2016年02月27日 09:32:52   投稿:hebedich  
讓計算機程序并發(fā)的運行是一個經(jīng)常被討論的話題,今天我想討論一下Python下的各種并發(fā)方式。

GIL

在Python中,由于歷史原因(GIL),使得Python中多線程的效果非常不理想.GIL使得任何時刻Python只能利用一個CPU核,并且它的調(diào)度算法簡單粗暴:多線程中,讓每個線程運行一段時間t,然后強行掛起該線程,繼而去運行其他線程,如此周而復始,直到所有線程結(jié)束.

這使得無法有效利用計算機系統(tǒng)中的"局部性",頻繁的線程切換也對緩存不是很友好,造成資源的浪費.

據(jù)說Python官方曾經(jīng)實現(xiàn)了一個去除GIL的Python解釋器,但是其效果還不如有GIL的解釋器,遂放棄.后來Python官方推出了"利用多進程替代多線程"的方案,在Python3中也有concurrent.futures這樣的包,讓我們的程序編寫可以做到"簡單和性能兼得".

多進程/多線程+Queue

一般來說,在Python中編寫并發(fā)程序的經(jīng)驗是:計算密集型任務使用多進程,IO密集型任務使用多進程或者多線程.另外,因為涉及到資源共享,所以需要同步鎖等一系列麻煩的步驟,代碼編寫不直觀.另外一種好的思路是利用多進程/多線程+Queue的方法,可以避免加鎖這樣麻煩低效的方式.

現(xiàn)在在Python2中利用Queue+多進程的方法來處理一個IO密集型任務.

假設現(xiàn)在需要下載多個網(wǎng)頁內(nèi)容并進行解析,單進程的方式效率很低,所以使用多進程/多線程勢在必行.
我們可以先初始化一個tasks隊列,里面將要存儲的是一系列dest_url,同時開啟4個進程向tasks中取任務然后執(zhí)行,處理結(jié)果存儲在一個results隊列中,最后對results中的結(jié)果進行解析.最后關(guān)閉兩個隊列.

下面是一些主要的邏輯代碼.

# -*- coding:utf-8 -*-

#IO密集型任務
#多個進程同時下載多個網(wǎng)頁
#利用Queue+多進程
#由于是IO密集型,所以同樣可以利用threading模塊

import multiprocessing

def main():
  tasks = multiprocessing.JoinableQueue()
  results = multiprocessing.Queue()
  cpu_count = multiprocessing.cpu_count() #進程數(shù)目==CPU核數(shù)目

  create_process(tasks, results, cpu_count)  #主進程馬上創(chuàng)建一系列進程,但是由于阻塞隊列tasks開始為空,副進程全部被阻塞
  add_tasks(tasks) #開始往tasks中添加任務
  parse(tasks, results) #最后主進程等待其他線程處理完成結(jié)果


def create_process(tasks, results, cpu_count):
  for _ in range(cpu_count):
    p = multiprocessing.Process(target=_worker, args=(tasks, results)) #根據(jù)_worker創(chuàng)建對應的進程
    p.daemon = True #讓所有進程可以隨主進程結(jié)束而結(jié)束
    p.start() #啟動

def _worker(tasks, results):
  while True:  #因為前面所有線程都設置了daemon=True,故不會無限循環(huán)
    try:
      task = tasks.get()  #如果tasks中沒有任務,則阻塞
      result = _download(task)
      results.put(result)  #some exceptions do not handled
    finally:
      tasks.task_done()

def add_tasks(tasks):
  for url in get_urls(): #get_urls() return a urls_list
    tasks.put(url)

def parse(tasks, results):
  try: 
    tasks.join()
  except KeyboardInterrupt as err:
    print "Tasks has been stopped!"
    print err

  while not results.empty():
    _parse(results)



if __name__ == '__main__':
  main()

利用Python3中的concurrent.futures包

在Python3中可以利用concurrent.futures包,編寫更加簡單易用的多線程/多進程代碼.其使用感覺和Java的concurrent框架很相似(借鑒?)
比如下面的簡單代碼示例

def handler():
  futures = set()

  with concurrent.futures.ProcessPoolExecutor(max_workers=cpu_count) as executor:
    for task in get_task(tasks):
      future = executor.submit(task)
      futures.add(future)

def wait_for(futures):
  try:
    for future in concurrent.futures.as_completed(futures):
      err = futures.exception()
      if not err:
        result = future.result()
      else:
        raise err
  except KeyboardInterrupt as e:
    for future in futures:
      future.cancel()
    print "Task has been canceled!"
    print e
  return result

總結(jié)

要是一些大型Python項目也這般編寫,那么效率也太低了.在Python中有許多已有的框架使用,使用它們起來更加高效.
但是自己的一些"小打小鬧"的程序這樣來編寫還是不錯的.:)

相關(guān)文章

  • 使用pyshp包進行shapefile文件修改的例子

    使用pyshp包進行shapefile文件修改的例子

    今天小編就為大家分享一篇使用pyshp包進行shapefile文件修改的例子,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2019-12-12
  • django框架ModelForm組件用法詳解

    django框架ModelForm組件用法詳解

    這篇文章主要介紹了django框架ModelForm組件用法,結(jié)合實例形式較為詳細的分析了Django框架ModelForm組件相關(guān)功能、原理、使用方法及操作注意事項,需要的朋友可以參考下
    2019-12-12
  • python?HZK16字庫使用詳解

    python?HZK16字庫使用詳解

    這篇文章主要介紹了python?HZK16字庫使用,本文結(jié)合實例代碼給大家講解的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-02-02
  • Python3網(wǎng)絡爬蟲中的requests高級用法詳解

    Python3網(wǎng)絡爬蟲中的requests高級用法詳解

    本節(jié)我們再來了解下 Requests 的一些高級用法,如文件上傳,代理設置,Cookies 設置等等。感興趣的朋友跟隨小編一起看看吧
    2019-06-06
  • 讓你一文弄懂Pandas文本數(shù)據(jù)處理

    讓你一文弄懂Pandas文本數(shù)據(jù)處理

    文本數(shù)據(jù)具有數(shù)據(jù)維度高、數(shù)據(jù)量大且語義復雜等特點,是一種較為復雜的數(shù)據(jù)類型,下面這篇文章主要給大家介紹了關(guān)于Pandas文本數(shù)據(jù)處理的相關(guān)資料,文中通過示例代碼介紹的非常詳細,需要的朋友可以參考下
    2021-08-08
  • 利用Matplotlib繪制折線圖、散點圖、柱狀圖、直方圖、餅圖的實例

    利用Matplotlib繪制折線圖、散點圖、柱狀圖、直方圖、餅圖的實例

    這篇文章主要介紹了利用Matplotlib繪制折線圖、散點圖、柱狀圖、直方圖、餅圖的實例代碼,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-09-09
  • python實現(xiàn)將內(nèi)容分行輸出

    python實現(xiàn)將內(nèi)容分行輸出

    本文給大家分享的是使用python實現(xiàn)將一行里的內(nèi)容進行分行輸出,一共給出了四種方法,小伙伴們可以參考下
    2015-11-11
  • Python 解析xml文件的示例

    Python 解析xml文件的示例

    這篇文章主要介紹了Python 解析xml文件的示例,幫助大家更好的利用python處理文件,感興趣的朋友可以了解下
    2020-09-09
  • 在Python的Django框架中顯示對象子集的方法

    在Python的Django框架中顯示對象子集的方法

    這篇文章主要介紹了在Python的Django框架中顯示對象子集的方法,即queryset的參數(shù)的使用相關(guān),需要的朋友可以參考下
    2015-07-07
  • 用python-webdriver實現(xiàn)自動填表的示例代碼

    用python-webdriver實現(xiàn)自動填表的示例代碼

    這篇文章主要介紹了用python-webdriver實現(xiàn)自動填表的示例代碼,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2021-01-01

最新評論