教育行業(yè)A股IPO第一股(股票代碼 003032)

全國(guó)咨詢(xún)/投訴熱線:400-618-4000

Python線程與進(jìn)程手記

更新時(shí)間:2018年09月21日17時(shí)23分 來(lái)源:傳智播客 瀏覽次數(shù):

#線程應(yīng)用的第一種方式:thread模塊是比較底層的模塊
#import thread:引用的模塊
#thread.start_new_thread(defName,()):線程的創(chuàng)建
#thread.exit_thread():線程的結(jié)束

#線程應(yīng)用的第二種方式:threading模塊是對(duì)thread做了一些包裝,可以更方便被引用
#import threading:引用的模塊
#myThread=threading.Thread(target=defName,args=('Alice',)):線程的創(chuàng)建
#myThread.start():線程開(kāi)始執(zhí)行
#num=len(threading.enumerate):線程數(shù)量的查看
#線程應(yīng)用的第三種方式:創(chuàng)建一個(gè)線程類(lèi),繼承基類(lèi):threading.Thread 。重寫(xiě)def run(self):方法。需要運(yùn)行的內(nèi)容,寫(xiě)在run方法里面。
#class MyThread(threading.Thread):創(chuàng)建類(lèi)的對(duì)象
#可以進(jìn)行重構(gòu)函數(shù)的對(duì)應(yīng)擴(kuò)展:def __init__(self,name,time):threading.Thread.__init__(self,name='對(duì)應(yīng)的線程名字')
#myThread=MyThread():創(chuàng)建對(duì)象
#myThread.start():線程開(kāi)始執(zhí)行
------------------------------線程同步之互斥鎖---------------------------
#線程同步之互斥鎖
#互斥鎖同步:線程同步能夠保證多個(gè)線程安全訪問(wèn)競(jìng)爭(zhēng)資源,最簡(jiǎn)單的同步機(jī)制是引用互斥鎖?;コ怄i為資源引入一個(gè)狀態(tài):鎖定/非鎖定。某個(gè)線程要更改共享數(shù)據(jù)時(shí),先將其鎖定,此時(shí)資源的狀態(tài)為“鎖定”,其他線程不能更改;直到該線程釋放資源,將資源的狀態(tài)變成“非鎖定”,其他的線程才能再次鎖定該資源。
#mutex=threading.Lock():創(chuàng)建互斥鎖
#if mutex.acquire([blocking]):互斥鎖鎖定狀態(tài),返回值不為0表示上鎖成功
#        鎖定方法acquire可以有一個(gè)blocking參數(shù)。如果設(shè)定blocking為T(mén)rue,則當(dāng)前線程會(huì)堵塞,直到獲取到這個(gè)鎖為止(如果沒(méi)有指定,那么默認(rèn)為T(mén)rue);如果設(shè)定blocking為False,則當(dāng)前線程不會(huì)堵塞
#mutex.release():互斥鎖釋放狀態(tài)

------------------------------線程同步至可重入鎖---------------------------
#線程同步之可重入鎖
#RLock內(nèi)部維護(hù)著一個(gè)Lock和一個(gè)counter變量,counter記錄了acquire的次數(shù),從而使得資源可以被多次acquire。直到一個(gè)線程所有的acquire都被release,其他的線程才能獲得資源:
#mutex=threading.RLock():創(chuàng)建可重入鎖
#mutex.acquire():可重入鎖鎖定狀態(tài)
#mutex.release():可重入鎖釋放狀態(tài)
------------------------------線程同步之條件變量---------------------------
#線程同步之條件變量
#Python提供的Condition對(duì)象提供了對(duì)復(fù)雜線程同步問(wèn)題的支持。Condition被稱(chēng)為條件變量,除了提供與Lock類(lèi)似的acquire和release方法外,還提供了wait和notify方法。線程首先acquire一個(gè)條件變量,然后判斷一些條件。如果條件不滿足則wait;如果條件滿足,進(jìn)行一些處理改變條件后,通過(guò)notify方法通知其他線程,其他處于wait狀態(tài)的線程接到通知后會(huì)重新判斷條件。不斷的重復(fù)這一過(guò)程,從而解決復(fù)雜的同步問(wèn)題。
#Condition對(duì)象維護(hù)了一個(gè)鎖(Lock/RLock)和一個(gè)waiting池。線程通過(guò)acquire獲得Condition對(duì)象,當(dāng)調(diào)用wait方法時(shí),線程會(huì)釋放Condition內(nèi)部的鎖并進(jìn)入blocked狀態(tài),同時(shí)在waiting池中記錄這個(gè)線程。當(dāng)調(diào)用notify方法時(shí),Condition對(duì)象會(huì)從waiting池中挑選一個(gè)線程,通知其調(diào)用acquire方法嘗試取到鎖。
#Condition對(duì)象的構(gòu)造函數(shù)可以接受一個(gè)Lock/RLock對(duì)象作為參數(shù),如果沒(méi)有指定,則Condition對(duì)象會(huì)在內(nèi)部自行創(chuàng)建一個(gè)RLock。
#除了notify方法外,Condition對(duì)象還提供了notifyAll方法,可以通知waiting池中的所有線程嘗試acquire內(nèi)部鎖。由于上述機(jī)制,處于waiting狀態(tài)的線程只能通過(guò)notify方法喚醒,所以notifyAll的作用在于防止有線程永遠(yuǎn)處于沉默狀態(tài)。
#con=threading.Condition():創(chuàng)建條件變量
#con.acquire():條件變量鎖定狀態(tài)
#con.wait():線程釋放Condition內(nèi)部的鎖并進(jìn)入blocked狀態(tài),同時(shí)在waiting池中記錄這個(gè)線程
#con.notify():Condition對(duì)象會(huì)從waiting池中挑選一個(gè)線程,通知其調(diào)用acquire方法嘗試取到鎖
#con.notifyAll():?jiǎn)拘阉刑幱趙aiting池中的所有線程,防止有線程永遠(yuǎn)處于沉默狀態(tài)
#con.release():條件變量釋放狀態(tài)

------------------------------線程同步之隊(duì)列---------------------------
#from Queue import Queue:進(jìn)行對(duì)應(yīng)的隊(duì)列包的引用
#queue=Queue():隊(duì)列的創(chuàng)建
#queue.qsize():獲取隊(duì)列中內(nèi)容的數(shù)量
#queue.put(內(nèi)容):向隊(duì)列中添加對(duì)應(yīng)的數(shù)據(jù)信息
#queue.set():從隊(duì)列中取出對(duì)應(yīng)的數(shù)據(jù)
#queue.empty():查看當(dāng)前隊(duì)列內(nèi)容是否為空
 線程隊(duì)列實(shí)現(xiàn)生產(chǎn)者消費(fèi)者
------------------------------線程間通信---------------------------
threading.Event可以使一個(gè)線程等待其他線程的通知。其內(nèi)置了一個(gè)標(biāo)志,初始值為False。線程通過(guò)wait()方法進(jìn)入等待狀態(tài),直到另一個(gè)線程調(diào)用set()方法將內(nèi)置標(biāo)志設(shè)置為T(mén)rue時(shí),Event通知所有等待狀態(tài)的線程恢復(fù)運(yùn)行。還可以通過(guò)isSet()方法查詢(xún)Envent對(duì)象內(nèi)置狀態(tài)的當(dāng)前值。
#event=threading.Event():進(jìn)行對(duì)應(yīng)Envent對(duì)象的創(chuàng)建
#self.threadEvent=event :重構(gòu)對(duì)應(yīng)threading.Thread基類(lèi)中的__init__的方法。 
#self.threadEvent.wait():使線程進(jìn)入等待狀態(tài)
#event.set():?jiǎn)?dòng)waiting池中等待的線程

------------------------------線程的合并和后臺(tái)線程---------------------------
python的Thread類(lèi)中還提供了join()方法,使得一個(gè)線程可以等待另一個(gè)線程執(zhí)行結(jié)束后再繼續(xù)運(yùn)行。這個(gè)方法還可以設(shè)定一個(gè)timeout參數(shù),避免無(wú)休止的等待。因?yàn)閮蓚€(gè)線程順序完成,看起來(lái)象一個(gè)線程,所以稱(chēng)為線程的合并。
默認(rèn)情況下,主線程在退出時(shí)會(huì)等待所有子線程的結(jié)束。如果希望主線程不等待子線程,而是在退出時(shí)自動(dòng)結(jié)束所有的子線程,就需要設(shè)置子線程為后臺(tái)線程(daemon)。方法是通過(guò)調(diào)用線程類(lèi)的setDaemon()方法。
#myThread.setDaemon(True):將該線程轉(zhuǎn)為后臺(tái)線程

------------------------------ThreadLocal---------------------------
global_dict={}
global_dict[threading.current_thread()]

------------------------------多進(jìn)程---------------------------
在Unix/Linux操作系統(tǒng)中,提供了一個(gè)fork()系統(tǒng)函數(shù),它非常特殊。
普通的函數(shù)調(diào)用,調(diào)用一次,返回一次,但是fork()調(diào)用一次,返回兩次,因?yàn)椴僮飨到y(tǒng)自動(dòng)把當(dāng)前進(jìn)程(稱(chēng)為父進(jìn)程)復(fù)制了一份(稱(chēng)為子進(jìn)程),然后,分別在父進(jìn)程和子進(jìn)程內(nèi)返回。
子進(jìn)程永遠(yuǎn)返回0,而父進(jìn)程返回子進(jìn)程的ID。
這樣做的理由是,一個(gè)父進(jìn)程可以fork出很多子進(jìn)程,所以,父進(jìn)程要記下每個(gè)子進(jìn)程的ID,而子進(jìn)程只需要調(diào)用getppid()就可以拿到父進(jìn)程的ID。
#import os :引用對(duì)應(yīng)的進(jìn)程包
#pid=os.fork():程序執(zhí)行到os.fork()時(shí),操作系統(tǒng)會(huì)創(chuàng)建一個(gè)新的進(jìn)程(子進(jìn)程),然后復(fù)制父進(jìn)程的所有信息到子進(jìn)程中,然后父進(jìn)程和子進(jìn)程都會(huì)從fork()函數(shù)中得到一個(gè)返回值,其進(jìn)程中這個(gè)值一定是0,而父進(jìn)程中是子進(jìn)程的 id號(hào)
#os.getpid():獲取當(dāng)前進(jìn)程的pid
#os.getppid():獲取父進(jìn)程的pid
------------------------------multiprocessing模塊---------------------------
#from multiprocessing import Process:multiprocessing模塊提供了一個(gè)Process類(lèi)來(lái)代表一個(gè)進(jìn)程對(duì)象。
#p=Process(target=run_proc,args=('test',)):創(chuàng)建對(duì)應(yīng)的進(jìn)程對(duì)象
#p.start():進(jìn)程的啟動(dòng)
#p.join():multiprocessing模塊提供了一個(gè)Process類(lèi)來(lái)代表一個(gè)進(jìn)程對(duì)象,下面的例子演示了啟動(dòng)一個(gè)子進(jìn)程并等待其結(jié)束
#multiprocessing.cpu_count():查看對(duì)應(yīng)的cpu核數(shù)
#pipe=multiprocessing.Pipe():創(chuàng)建一個(gè)管道,管道兩個(gè)端口調(diào)用分別為pipe[0],pipe[1]
#pipe[0].send(i):為管道一側(cè)進(jìn)行內(nèi)容的添加操作
#pipe[0].recv():獲取管道一側(cè)的內(nèi)容信息



作者:傳智播客Python+人工智能開(kāi)發(fā)培訓(xùn)學(xué)院
首發(fā):
http://python.itcast.cn/
0 分享到:
和我們?cè)诰€交談!