天天看點

python多程序和多線程一起使用_輕松實作Python中的多程序與多線程

原标題:輕松實作Python中的多程序與多線程

還沒關注?

今天我們來聊聊Python裡面的多程序與多線程程式設計模式。

01 多線程工作

在開始講今天的正文之前,先給大家介紹一個概念「多線程工作」,這個概念可能有的人聽過,也可能有的人平常工作中就是這麼做的。我再來給大家講講這個概念,所謂的「多線程工作」就是同時做好幾件事情。

拿我個人工作中例子來說,當我用Sql跑數的時候,資料不可能一下子就導出來,我會在一個螢幕上顯示Sql運作進度,在另一個螢幕上先做一會PPT,等Sql跑出來以後,我就又會迅速切換到處理剛剛導出來的資料。有的時候資料量很大,用Excel打開檔案可能需要幾分鐘的時間,這個時候Excel是處于運作狀态,我是沒法在Excel上做别的事情,我會去微信上去處理别人的一些問題,當檔案打開以後,我會迅速切換到Excel上繼續下一步處理,當我輸入一個公式以後,Excel可能又需要等待一會,這個時候我就可以再去做一些别的事情。

大家可以看到,我沒有在等一件事情徹底做完以後再去做另一件事情,而是在不同僚情之間迅速切換,這種工作方式就可以算是一種「多線程工作」。

「多線程工作」可以減少你等待的時間,大大提高你的工作效率。

02 多程序與多線程

了解了「多線程工作」以後,我們開始進入今天的正題,程式設計裡面的多線程和多程序。在上面的例子中Sql跑數可以算是一個程序、做PPT也可以算是一個程序、Excel處理資料還是一個程序。

程序下面還有一個更小的機關就是線程,一個程序由若幹個線程組成,Sql跑數這個程序可以由寫Sql、運作Sql、導出資料這幾個線程組成。同樣,PPT制作這個程序可以由明确主題、選模闆、列大綱、豐富頁面這幾個線程組成。

線程是程式執行的最小機關,一個程序可以由一個或多個線程組成,各個線程之間也是交叉執行。

這裡需要注意的是,多程序/多線程并不能做到同時去做好幾件事情,而是把不同的事情交叉着做,做一段時間任務a,然後強制停止,去做一會任務b,再停止,再去做任務c。之是以會覺得各個任務之間是同時進行的原因是是任務與任務之間切換速度足夠快,這樣看起來就像是多個任務同時在進行。

我們再來看兩個概念:

并行:指在同一時刻,有多條指令在多個處理器上同時執行;

并發:指在同一時刻,隻能有一條指令執行,但多個程序指令被快速輪換執行,使得在宏觀上具有多個程序同時執行的效果。

多份工作有多個人同時在做時就是并行,當多份工作由一個人交替在做時就是并發。在計算機中也是同樣的概念,計算機中CPU的核數就相當于人數,當計算機是單核多任務時就是并發;當計算機是多核且大于任務數時,就是并行。

目前電腦主流配置都是四核/八線程的,而實際工作的任務數大都大于四個,是以也是需要交替來執行具體任務的,也就是并發執行。

python多程式和多線程一起使用_輕松實作Python中的多程式與多線程

我電腦運作情況

上面就是關于多線程與多程序的一個簡單通俗的了解,一些太官方的解釋我就不在這裡放了,大家感興趣的可以去自行上網查。

03 多程序與多線程是如何提高效率的

假設做任務A需要1個小時、任務B需要1個小時、任務C需要一個小時,當我們每個任務做20分鐘以後切換到另一個任務,這樣做完三個任務需要的總時間是不會變的,不僅不會變,反而可能會增加,因為在不同任務之間切換是需要代價的,因為當你從一個任務切換到另一個任務時很有可能不記得剛剛做到哪裡了,還需要花時間想一想。那既然是這樣,我們為什麼還要用多程序/多線程這種處理任務的方式呢?我在第一小節裡面提過,「多線程工作」可以減少你等待的時間,大大提高你的工作效率。

是因為在實際工作中,有很多需要等待的地方,比如等待Excel打開,等待Sql跑出資料。多程序/多線程任務處理方式就是充分利用這些等待時間。讓你的大腦,計算機的大腦(CPU)得到充分的利用。如果要是沒有等待的時間,多程序/多線程的任務處理方式可能就不如單線程的了。

04 多程序與多線程是如何實作的

了解清楚了多程序與多線程是什麼,以及是如何提高處理任務的效率的以後,我們進入到硬幹貨部分,那就是具體多程序/多線程如何實作“同時”處理多任務的。

實作多任務的方式主要有以下幾種:

1、多程序模式

2、多線程模式

3、多程序+多線程

同時執行多個任務通常各個任務之間并不是沒有關聯的,而是需要互相通信和協調,有時,任務1必須暫停等待任務2完成後才能繼續執行,有時,任務3和任務4又不能同時執行,是以,多程序和多線程的程式的複雜度要遠遠高于我們前面寫的單程序單線程的程式。

4.1多程序模式

多程序就是一次啟動多個程序,每個程序隻有一個線程,但多個程序可以一起執行多個任務。一般程序數預設是電腦CPU核數,當你的電腦是四核的時候,你的電腦程序預設就是4個。

4.1.1參數詳解

在Python中我們借助多程序包multiprocessing來進行多程序任務處理方式,multiprocessing子產品提供了一個Process類來代表一個程序對象,

#Process參數

multiprocessing.Process(group=None, target=None, name=None, args=(), kwargs={}, *, daemon=None)

#group分組

#target表示調用對象,即函數

#name表示程序的别名

#args表示調用對象的位置參數元組,即函數的參數

#kwargs表示調用對象的字典

#Process常用方法

close() 關閉程序

is_alive() 程序是否在運作

join() 等待join語句之前的所有程式執行完畢以後再繼續往下運作,通常用于程序間的同步

start() 程序準備就緒,等待CPU排程

run() strat()調用run方法,如果執行個體化程序時沒有傳入target參數,這star執行預設run()方法

#Process常用屬性

pid程序ID

name 程序名字

4.1.2建立一個子程序

下面的例子示範了啟動一個子程序(即單程序)并等待其結束:

frommultiprocessing importProcess

importos

# 子程序要執行的代碼def run_proc(name):

print('Run child process %s (%s)...'% (name, os.getpid()))

if__name__=='__main__':

print('Parent process %s.'% os.getpid())#用來擷取主程序的程序ID

p = Process(target=run_proc, args=('test',))#執行個體化程序p,調用run_proc函數,傳入參數對象args

print('Child process will start.')

p.start()#程序準備就緒

p.join()#待所有程序執行完畢以後執行後續操作

print('Child process end.')

運作結果如下:

Process (876) start...

I (876) just created a childprocess (877).

I am childprocess (877) andmy parentis876.

一個子程序其實就和我們平常調用單一函數是一樣的。

4.1.3建立多個子程序

建立多個子程序(即多程序),其實就是多個函數随機同步運作。

建立多程序有兩種方法,一種是直接利用Process來建立多個子程序即可,如下:

frommultiprocessing importProcess

importrandom,time

defdo_task(task):

print('我正在做{}'.format(task))

time.sleep(random.randint(1,3))

defwrite_task(task):

print('我正在寫{}'.format(task))

time.sleep(random.randint(1,3))

if__name__ == "__main__":

p1 = Process(target=do_task,args=('PPT',))

p2 = Process(target=write_task,args=('Sql',))

p1.start()

p2.start()

輸出結果為:

我正在做PPT

我正在寫Sql

上面代碼表示同時啟動兩個程序,且兩個程序分别調用不同的函數,即做不同的任務。而且上面的任務數隻有兩個,當任務數(需要調用的函數)較多時,我們如果還用上述的方法建立多程序,就需要執行個體化多個程序對象,并且寫多行p.start()比較麻煩,聰明的前輩們肯定不會用這麼笨的方法,是以就有了程序池(Pool)。

multiprocessing.Pool = Pool(processes=None)#process為程序數

把上面的二程序用程序池表示以後的結果如下:

import multiprocessing

import random,time

def do_task(task):

print('我正在做{}'.format(task))

time.sleep(random.randint(1,3))

def write_task(task):

print('我正在寫{}'.format(task))

time.sleep(random.randint(1,3))

if__name__ == "__main__":

func_list=[do_task,write_task]

args_list=["PPT","Sql"]

pool=multiprocessing.Pool(2)

forfunc,args infunction_list,args_list:

pool.apply_async(func,arg)

print'Waiting for all subprocesses done...'

pool.close()

pool.join() #調用join之前,一定要先調用close() 函數,否則會出錯

print'All subprocesses done.'

輸出結果如下:

Waiting forall subprocesses done...

我正在做PPT

我正在寫Sql

All subprocesses done.

4.2多線程模式

多線程模式就是一次隻啟動一個程序,但是在這個程序裡面可以啟動多個線程,這樣多個線程就可以一起執行多個任務,在Python中我們要啟動多線程借助于threading子產品,用于 啟動多線程的子產品還有_thread子產品,但是threading子產品是封裝了_thread子產品,且比較進階,是以我們一般使用threading子產品即可。

4.2.1參數詳解

啟動多線程使用的是threading子產品中的Thread類,建構時使用的參數和方法與Process基本一緻,大家看看即可,這裡就不贅述了。

#參數

Thread(group=None, target=None, name=None, args=(), kwargs={})

#方法

isAlive()

get/setName(name) 擷取/設定線程名

start()

join()

4.2.2建立一個線程

建立一個線程就是調用一個函數。

importtime, threading

defdo_chioce(task):

print('我正在{}'.format(task))

time.sleep(random.randint(1,3))

if__name__ == "__main__":

t = threading.Thread(target=do_chioce,args=('選PPT模闆',))

t.start()

輸出結果為:

我正在選PPT模闆

4.2.3建立多個線程

建立多個線程就是調用多個函數。

importtime, threading

defdo_chioce(task):

print('我正在{}'.format(task))

time.sleep(random.randint(1,3))

defdo_content(task):

print('我正在{}'.format(task))

time.sleep(random.randint(1,3))

if__name__ == "__main__":

t1 = threading.Thread(target=do_chioce,args=('選PPT模闆',))

t2 = threading.Thread(target=do_content,args=('列PPT大綱',))

t1.start()

t2.start()

輸出結果為:

我正在選PPT模闆

我正在列PPT大綱

4.3多程序+多線程

多程序+多線程就是一次啟動多個程序,每個程序又啟動多個線程,這樣同時執行的任務就會很多,但是模型相對複雜,不建議使用。傳回搜狐,檢視更多

責任編輯: