python中的並發,python並發原理

本文目錄一覽:

python並發編程-進程池

在利用Python進行系統管理的時候,特別是同時操作多個文件目錄,或者遠程控制多台主機,並行操作可以節約大量的時間。多進程是實現並發的手段之一,需要注意的問題是:

例如當被操作對象數目不大時,可以直接利用multiprocessing中的Process動態成生多個進程,十幾個還好,但如果是上百個,上千個。。。手動的去限制進程數量卻又太過繁瑣,此時可以發揮進程池的功效。

我們就可以通過維護一個進程池來控制進程數目,比如httpd的進程模式,規定最小進程數和最大進程數..

ps: 對於遠程過程調用的高級應用程序而言,應該使用進程池,Pool可以提供指定數量的進程,供用戶調用,當有新的請求提交到pool中時,如果池還沒有滿,那麼就會創建一個新的進程用來執行該請求;但如果池中的進程數已經達到規定最大值,那麼該請求就會等待,直到池中有進程結束,就重用進程池中的進程。

創建進程池的類:如果指定numprocess為3,則進程池會從無到有創建三個進程,然後自始至終使用這三個進程去執行所有任務,不會開啟其他進程

參數介紹:

方法介紹:

主要方法:

其他方法(了解部分)

應用:

發現:並發開啟多個客戶端,服務端同一時間只有3個不同的pid,幹掉一個客戶端,另外一個客戶端才會進來,被3個進程之一處理

回調函數:

需要回調函數的場景:進程池中任何一個任務一旦處理完了,就立即告知主進程:我好了額,你可以處理我的結果了。主進程則調用一個函數去處理該結果,該函數即回調函數

我們可以把耗時間(阻塞)的任務放到進程池中,然後指定回調函數(主進程負責執行),這樣主進程在執行回調函數時就省去了I/O的過程,直接拿到的是任務的結果。

如果在主進程中等待進程池中所有任務都執行完畢後,再統一處理結果,則無需回調函數

python簡單的並發問題

#!/usr/bin/envpython#-*-coding:utf-8-*-#author:ChanghuaGongimporttime,threading#fromurllib.requestimportRequest,urlopenpy3#fromurllib.errorimportURLErrorpy3importurllib2#URLreq=urllib2.Request(‘

#!/usr/bin/env python

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

# author: Changhua Gong

import time,threading

# from urllib.request import Request, urlopen py3

# from urllib.error import URLError py3

import urllib2

#URL

req = urllib2.Request(”)

#

rule = {0:500,1:30}

”’

Rule規則:0:50,第一次運行不睡眠即為0,直接並發50次;1:20,第二秒,相當於睡眠1秒,然後並發20次,

如第三秒需並發500次,則rule = {0:50,1:20,1:500}

”’

#Open url

def geturl():

time_b = time.time()

try:

response = urllib2.urlopen(req)

print(response.read().decode(“utf-8”)) # 打印輸出內容

except urllib2.URLError as e:

if hasattr(e, ‘reason’):

print(‘We failed to reach a server.’)

print(‘Reason: ‘, e.reason)

elif hasattr(e, ‘code’):

print(‘The server couldn/’t fulfill the request.’)

print(‘Error code: ‘, e.code)

time_e = time.time()

print(“Thread %s runned for %ss” % (threading.current_thread().name, (time_e – time_b))) #線程訪問時效

if __name__==’__main__’:

for k in rule:

time.sleep(k)

for i in range(rule[k]):

t = threading.Thread(target=geturl)

t.start()

如何在Python中編寫並發程序

多進程/多線程+Queue

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

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

假設現在需要下載多個網頁內容並進行解析,單進程的方式效率很低,所以使用多進程/多線程勢在必行.

我們可以先初始化一個tasks隊列,裏面將要存儲的是一系列dest_url,同時開啟4個進程向tasks中取任務然後執行,處理結果存儲在一個results隊列中,最後對results中的結果進行解析.最後關閉兩個隊列.

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

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

#IO密集型任務

#多個進程同時下載多個網頁

#利用Queue+多進程

#由於是IO密集型,所以同樣可以利用threading模塊

import multiprocessing

def main():

tasks = multiprocessing.JoinableQueue()

results = multiprocessing.Queue()

cpu_count = multiprocessing.cpu_count() #進程數目==CPU核數目

create_process(tasks, results, cpu_count) #主進程馬上創建一系列進程,但是由於阻塞隊列tasks開始為空,副進程全部被阻塞

add_tasks(tasks) #開始往tasks中添加任務

parse(tasks, results) #最後主進程等待其他線程處理完成結果

def create_process(tasks, results, cpu_count):

for _ in range(cpu_count):

p = multiprocessing.Process(target=_worker, args=(tasks, results)) #根據_worker創建對應的進程

p.daemon = True #讓所有進程可以隨主進程結束而結束

p.start() #啟動

def _worker(tasks, results):

while True: #因為前面所有線程都設置了daemon=True,故不會無限循環

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

總結

要是一些大型Python項目也這般編寫,那麼效率也太低了.在Python中有許多已有的框架使用,使用它們起來更加高效.

但是自己的一些”小打小鬧”的程序這樣來編寫還是不錯的.:)

python高並發怎麼解決

某個時間段內,數據湧來,這就是並發。如果數據量很大,就是高並發

高並發的解決方法:

1、隊列、緩衝區

假設只有一個窗口,陸續湧入食堂的人,排隊打菜是比較好的方式

所以,排隊(隊列)是一種天然解決並發的辦法

排隊就是把人排成 隊列,先進先出,解決了資源使用的問題

排成的隊列,其實就是一個緩衝地帶,就是 緩衝區

假設女生優先,每次都從這個隊伍中優先選出女生出來先打飯,這就是 優先隊列

例如queue模塊的類Queue、LifoQueue、PriorityQueue(小頂堆實現)

2、爭搶

只開一個窗口,有可能沒有秩序,也就是誰擠進去就給誰打飯

擠到窗口的人佔據窗口,直到打到飯菜離開

其他人繼續爭搶,會有一個人佔據着窗口,可以視為鎖定窗口,窗口就不能為其他人提供服務了。

這是一種鎖機制

誰搶到資源就上鎖,排他性的鎖,其他人只能等候

爭搶也是一種高並發解決方案,但是,這樣可能不好,因為有可能有人很長時間搶不到

3、預處理

如果排長隊的原因,是由於每個人打菜等候時間長,因為要吃的菜沒有,需要現做,沒打着飯不走開,鎖定着窗口

食堂可以提前統計大多數人最愛吃的菜品,將最愛吃的80%的熱門菜,提前做好,保證供應,20%的冷門菜,現做

這樣大多數人,就算鎖定窗口,也很快打到飯菜走了,快速釋放窗口

一種提前加載用戶需要的數據的思路,預處理 思想,緩存常用

更多Python知識,請關註:Python自學網!!

如何優雅的編寫Python並發程序

在Python中,由於歷史原因(GIL),使得Python中多線程的效果非常不理想.GIL使得任何時刻Python只能利用一個CPU核,並

且它的調度算法簡單粗暴:多線程中,讓每個線程運行一段時間t,然後強行掛起該線程,繼而去運行其他線程,如此周而復始,直到所有線程結束.

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

據說Python官方曾經實現了一個去除GIL的Python解釋器,但是其效果還不如有GIL的解釋器,遂放棄.後來Python官方推出了”利

用多進程替代多線程”的方案,在Python3中也有concurrent.futures這樣的包,讓我們的程序編寫可以做到”簡單和性能兼得”.

多進程/多線程+Queue

一般來說,在Python中編寫並發程序的經驗是:計算密集型任務使用多進程,IO密集型任務使用多進程或者多線程.另外,因為涉及到資源共享,所

以需要同步鎖等一系列麻煩的步驟,代碼編寫不直觀.另外一種好的思路是利用多進程/多線程+Queue的方法,可以避免加鎖這樣麻煩低效的方式.

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

假設現在需要下載多個網頁內容並進行解析,單進程的方式效率很低,所以使用多進程/多線程勢在必行.

Python進程之並行與並發的區別

並行 : 

當系統有一個以上CPU時,則進程的操作有可能非並發。當一個CPU執行一個進程時,另一個CPU可以執行另一個進程,兩個進程互不搶佔CPU資源,可以同時進行,這種方式我們稱之為並行。

並發 :

當有多個進程在操作時,如果系統只有一個CPU,則它根本不可能真正同時執行一個以上的進程,它只能把CPU運行時間劃分成若干個時間段,再將時間 段分配給各個進程執行,在一個時間段的進程代碼運行時,其它進程處於掛起狀,這種方式我們稱之為並發。

區別:

並發和並行是即相似又有區別的兩個概念,並行是指兩個或者多個事件在同一時刻同時執行,而並發是指兩個或多個事件通過時間片輪流被執行。在多道程序環境下,並發性是指在一段時間內宏觀上有多個程序在同時運行,但在單核CPU中,同一時刻僅能有一道程序執行,故微觀上這些程序只能是分時地交替執行。倘若在計算機中有多個CPU,則這些可以並發執行的程序便可被分配到多個處理機上,實現並行執行,即利用每個處理機來處理一個可並發執行的程序,這樣,多個程序便可以同時執行。

相關推薦:《Python視頻教程》

進程的狀態如下圖所示

在了解其他概念之前,我們首先要了解進程的幾個狀態。在程序運行的過程中,由於被操作系統的調度算法控制,程序會進入幾個狀態:就緒,運行和阻塞。

(1)就緒(Ready)狀態

當進程已分配到除CPU以外的所有必要的資源,只要獲得處理機便可立即執行,這時的進程狀態稱為就緒狀態。

(2)執行/運行(Running)狀態當進程已獲得處理機,其程序正在處理機上執行,此時的進程狀態稱為執行狀態。

(3)阻塞(Blocked)狀態正在執行的進程,由於等待某個事件發生而無法執行時,便放棄處理機而處於阻塞狀態。引起進程阻塞的事件可有多種,例如,等待I/O完成、申請緩衝區不能滿足、等待信件(信號)等。

相關推薦:

一文帶你讀懂Python中的進程

原創文章,作者:ZWEL,如若轉載,請註明出處:https://www.506064.com/zh-hk/n/139488.html

(0)
打賞 微信掃一掃 微信掃一掃 支付寶掃一掃 支付寶掃一掃
ZWEL的頭像ZWEL
上一篇 2024-10-04 00:22
下一篇 2024-10-04 00:22

相關推薦

  • Python列表中負數的個數

    Python列表是一個有序的集合,可以存儲多個不同類型的元素。而負數是指小於0的整數。在Python列表中,我們想要找到負數的個數,可以通過以下幾個方面進行實現。 一、使用循環遍歷…

    編程 2025-04-29
  • Python中引入上一級目錄中函數

    Python中經常需要調用其他文件夾中的模塊或函數,其中一個常見的操作是引入上一級目錄中的函數。在此,我們將從多個角度詳細解釋如何在Python中引入上一級目錄的函數。 一、加入環…

    編程 2025-04-29
  • Python周杰倫代碼用法介紹

    本文將從多個方面對Python周杰倫代碼進行詳細的闡述。 一、代碼介紹 from urllib.request import urlopen from bs4 import Bea…

    編程 2025-04-29
  • Python計算陽曆日期對應周幾

    本文介紹如何通過Python計算任意陽曆日期對應周幾。 一、獲取日期 獲取日期可以通過Python內置的模塊datetime實現,示例代碼如下: from datetime imp…

    編程 2025-04-29
  • 如何查看Anaconda中Python路徑

    對Anaconda中Python路徑即conda環境的查看進行詳細的闡述。 一、使用命令行查看 1、在Windows系統中,可以使用命令提示符(cmd)或者Anaconda Pro…

    編程 2025-04-29
  • Python清華鏡像下載

    Python清華鏡像是一個高質量的Python開發資源鏡像站,提供了Python及其相關的開發工具、框架和文檔的下載服務。本文將從以下幾個方面對Python清華鏡像下載進行詳細的闡…

    編程 2025-04-29
  • 蝴蝶優化算法Python版

    蝴蝶優化算法是一種基於仿生學的優化算法,模仿自然界中的蝴蝶進行搜索。它可以應用於多個領域的優化問題,包括數學優化、工程問題、機器學習等。本文將從多個方面對蝴蝶優化算法Python版…

    編程 2025-04-29
  • Python程序需要編譯才能執行

    Python 被廣泛應用於數據分析、人工智能、科學計算等領域,它的靈活性和簡單易學的性質使得越來越多的人喜歡使用 Python 進行編程。然而,在 Python 中程序執行的方式不…

    編程 2025-04-29
  • Python字典去重複工具

    使用Python語言編寫字典去重複工具,可幫助用戶快速去重複。 一、字典去重複工具的需求 在使用Python編寫程序時,我們經常需要處理數據文件,其中包含了大量的重複數據。為了方便…

    編程 2025-04-29
  • python強行終止程序快捷鍵

    本文將從多個方面對python強行終止程序快捷鍵進行詳細闡述,並提供相應代碼示例。 一、Ctrl+C快捷鍵 Ctrl+C快捷鍵是在終端中經常用來強行終止運行的程序。當你在終端中運行…

    編程 2025-04-29

發表回復

登錄後才能評論