python第10天(上)
multiprocessing包是Python中的多進程管理包。與threading.Thread類似,它可以利用multiprocessing.Process對象來創(chuàng)建一個進程。該進程可以運行在Python程序內(nèi)部編寫的函數(shù)。該Process對象與Thread對象的用法相同,也有start(), run(), join()的方法。此外multiprocessing包中也有Lock/Event/Semaphore/Condition類 (這些對象可以像多線程那樣,通過參數(shù)傳遞給各個進程),用以同步進程,其用法與threading包中的同名類一致。所以,multiprocessing的很大一部份與threading使用同一套API,只不過換到了多進程的情境
調(diào)用方法一:
import multiprocessing#多進程包 import time def visit(name):time.sleep(1)print('hello', name,time.ctime())if __name__ == '__main__':p_list=[]for i in range(3):p = multiprocessing.Process(target=visit, args=('alvin',))#創(chuàng)建子進程對象p_list.append(p)p.start()#開啟進程for i in p_list:p.join()#與線程意義先疼痛print('end')調(diào)用方法二:
class MyProcess(Process):def run(self):time.sleep(1)print ('hello', self.name,time.ctime())if __name__ == '__main__':p_list=[]for i in range(3):p = MyProcess()p.start()p_list.append(p)for p in p_list:p.join()print('end')一:pid
class progress(multiprocessing.Process):def run(self):time.sleep(2)print("process name",self.name)print("parent process id",os.getppid(),time.time())print("process id",os.getpid(),time.time()) if __name__=="__main__":print("main process line")progress.run(progress)print("----------")t1=progress()t2=progress()t1.start()t2.start()#主進程的parent process id 33440 1550129555.0609472 #主進程的process id 21996 1550129555.0609472 #子進程process name progress-1parent process id 21996 1550129557.234302process id 29496 1550129557.234302二:方法與屬性
-
is_alive():返回進程是否在運行。
-
join([timeout]):阻塞當(dāng)前上下文環(huán)境的進程程,直到調(diào)用此方法的進程終止或到達指定的timeout(可選參數(shù))。
-
start():進程準(zhǔn)備就緒,等待CPU調(diào)度
-
run():strat()調(diào)用run方法,如果實例進程時未制定傳入target,這star執(zhí)行t默認(rèn)run()方法。
- terminate():不管任務(wù)是否完成,立即停止工作進程
-
daemon:和線程的setDeamon功能一樣
-
name:進程名字。
-
pid:進程號
?一:進程隊列queque
import multiprocessing,time def foo(parad):time.sleep(1)print("子進程隊列id",id(parad))parad.put("name")parad.put({"name":"alex"}) if __name__=="__main__":p_list=[]parad=multiprocessing.Queue()#創(chuàng)建一個進程隊列print("主進程隊列",id(parad))for i in range(3):progress=multiprocessing.Process(target=foo,args=(parad,))progress.start()print(parad.get())print(parad.get())二:管道pipe
- pipe()函數(shù)返回一對通過一個雙向管道鏈接的鏈接對象
- parent_conn, child_conn = multiprocessing.Pipe()#創(chuàng)建一個管道對象
- parent_conn.recv()#接收 parent_conn.send()#發(fā)數(shù)據(jù)
- The two connection objects returned by?Pipe()?represent the two ends of the pipe. Each connection object has?send()?and?recv()?methods (among others). Note that data in a pipe may become corrupted if two processes (or threads) try to read from or write to the?same?end of the pipe at the same time. Of course there is no risk of corruption from processes using different ends of the pipe at the same time
三:manager
Queue和pipe只是實現(xiàn)了數(shù)據(jù)交互,并沒實現(xiàn)數(shù)據(jù)共享,即一個進程去更改另一個進程的數(shù)據(jù)。
A manager object returned by?Manager()?controls a server process which holds Python objects and allows other processes to manipulate them using proxies.
A manager returned by?Manager()?will support types?list,?dict,?Namespace,?Lock,?RLock,?Semaphore,?BoundedSemaphore,?Condition,?Event,?Barrier,?Queue,?Value?and?Array. For example:
def foo(dict,list,i,string):dict["name"]="tom"list[0]=5list.append(i)string="i am tom"print("son process",id(dict),id(list)) if __name__=="__main__":with multiprocessing.Manager() as manager:dict=manager.dict({"name":"alex"})list=manager.list([1,2,3,4])string=manager.Value("i am alex")p_list=[]for i in range(2):progress=multiprocessing.Process(target=foo,args=(dict,list,i,string))p_list.append(progress)progress.start()for i in p_list:i.join()print(dict)print(list)print(string)print("father process", id(dict), id(list))進程池內(nèi)部維護一個進程序列,當(dāng)使用時,則去進程池中獲取一個進程,如果進程池序列中沒有可供使用的進進程,那么程序就會等待,直到進程池中有可用進程為止
進程池中的方法:
- apply 從進程池里取一個進程并同步執(zhí)行
- apply_async 從進程池里取出一個進程并異步執(zhí)行
- terminate 立刻關(guān)閉進程池
- join 主進程等待所有子進程執(zhí)行完畢,必須在close或terminete之后
- close 等待所有進程結(jié)束才關(guān)閉線程池
?
所謂協(xié)程又稱為微線程,我們在進程在創(chuàng)建時, 需要耗費時間和cpu資源;在創(chuàng)建多線程時,也需要消耗時間和資源。利用多協(xié)程的運行過程中,始終只要一個線程, 不存在創(chuàng)建線程和銷毀線程需要的時間; 也沒有線程切換的開銷, 任務(wù)需要開啟線程數(shù)越多, 協(xié)程的優(yōu)勢越明顯;更不需要多線程的鎖機制(GIL)。
協(xié)程擁有自己的寄存器上下文和棧。協(xié)程調(diào)度切換時,將寄存器上下文和棧保存到其他地方,在切回來的時候,恢復(fù)先前保存的寄存器上下文和棧。因此:協(xié)程能保留上一次調(diào)用時的狀態(tài)(即所有局部狀態(tài)的一個特定組合),每次過程重入時,就相當(dāng)于進入上一次調(diào)用的狀態(tài),換種說法:進入上一次離開時所處邏輯流的位置。
協(xié)程的優(yōu)點:
(1)無需線程上下文切換的開銷,協(xié)程避免了無意義的調(diào)度,由此可以提高性能(但也因此,程序員必須自己承擔(dān)調(diào)度的責(zé)任,同時,協(xié)程也失去了標(biāo)準(zhǔn)線程使用多CPU的能力)
(2)無需原子操作鎖定及同步的開銷
(3)方便切換控制流,簡化編程模型
(4)高并發(fā)+高擴展性+低成本:一個CPU支持上萬的協(xié)程都不是問題。所以很適合用于高并發(fā)處理。
協(xié)程的缺點:
(1)無法利用多核資源:協(xié)程的本質(zhì)是個單線程,它不能同時將 單個CPU 的多個核用上,協(xié)程需要和進程配合才能運行在多CPU上.當(dāng)然我們?nèi)粘K帉懙慕^大部分應(yīng)用都沒有這個必要,除非是cpu密集型應(yīng)用。
(2)進行阻塞(Blocking)操作(如IO時)會阻塞掉整個程序
?
def consumer(name):print("我要吃包子")while True:baozi=yieldprint("%s eating %s 包子"%(name,baozi)) def producer(name):c1.__next__()c2.__next__()n=0while True:print("\033[32;1m[producer]\033[0m is making baozi %s and %s" % (n, n + 1))c1.send(n)c2.send(n+1)n+=2if __name__ == '__main__':c1=consumer("alex")c2=consumer("tom")p1=producer("cookie") import greenlet def test1():print(12)g2.switch()print(34)g2.switch()print(96) def test2():print(56)g1.switch()print(78) g1=greenlet.greenlet(test1)#創(chuàng)建一個協(xié)程對象 g2=greenlet.greenlet(test2) g1.switch()#啟動協(xié)程/切換協(xié)程gevnet是協(xié)程之間的自動切換
?
import gevent def func1():print(12)gevent.sleep(2)print(56)def func2():print(34)gevent.sleep(1)print(78) t1=gevent.spawn(func1)#創(chuàng)建一個線程對象 t2=gevent.spawn(func2) print(t1) gevent.joinall([t1,t2])#添加線程對象,并運行線程
?
?
轉(zhuǎn)載于:https://www.cnblogs.com/Mr-l/p/10373862.html
總結(jié)
以上是生活随笔為你收集整理的python第10天(上)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: php 安装redis php扩展
- 下一篇: IDEA编译的JAR包运行出现“没有主清