python第10天(上)
multiprocessing包是Python中的多進程管理包。與threading.Thread類似,它可以利用multiprocessing.Process對象來創建一個進程。該進程可以運行在Python程序內部編寫的函數。該Process對象與Thread對象的用法相同,也有start(), run(), join()的方法。此外multiprocessing包中也有Lock/Event/Semaphore/Condition類 (這些對象可以像多線程那樣,通過參數傳遞給各個進程),用以同步進程,其用法與threading包中的同名類一致。所以,multiprocessing的很大一部份與threading使用同一套API,只不過換到了多進程的情境
調用方法一:
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',))#創建子進程對象p_list.append(p)p.start()#開啟進程for i in p_list:p.join()#與線程意義先疼痛print('end')調用方法二:
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]):阻塞當前上下文環境的進程程,直到調用此方法的進程終止或到達指定的timeout(可選參數)。
-
start():進程準備就緒,等待CPU調度
-
run():strat()調用run方法,如果實例進程時未制定傳入target,這star執行t默認run()方法。
- terminate():不管任務是否完成,立即停止工作進程
-
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()#創建一個進程隊列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()函數返回一對通過一個雙向管道鏈接的鏈接對象
- parent_conn, child_conn = multiprocessing.Pipe()#創建一個管道對象
- parent_conn.recv()#接收 parent_conn.send()#發數據
- 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只是實現了數據交互,并沒實現數據共享,即一個進程去更改另一個進程的數據。
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))進程池內部維護一個進程序列,當使用時,則去進程池中獲取一個進程,如果進程池序列中沒有可供使用的進進程,那么程序就會等待,直到進程池中有可用進程為止
進程池中的方法:
- apply 從進程池里取一個進程并同步執行
- apply_async 從進程池里取出一個進程并異步執行
- terminate 立刻關閉進程池
- join 主進程等待所有子進程執行完畢,必須在close或terminete之后
- close 等待所有進程結束才關閉線程池
?
所謂協程又稱為微線程,我們在進程在創建時, 需要耗費時間和cpu資源;在創建多線程時,也需要消耗時間和資源。利用多協程的運行過程中,始終只要一個線程, 不存在創建線程和銷毀線程需要的時間; 也沒有線程切換的開銷, 任務需要開啟線程數越多, 協程的優勢越明顯;更不需要多線程的鎖機制(GIL)。
協程擁有自己的寄存器上下文和棧。協程調度切換時,將寄存器上下文和棧保存到其他地方,在切回來的時候,恢復先前保存的寄存器上下文和棧。因此:協程能保留上一次調用時的狀態(即所有局部狀態的一個特定組合),每次過程重入時,就相當于進入上一次調用的狀態,換種說法:進入上一次離開時所處邏輯流的位置。
協程的優點:
(1)無需線程上下文切換的開銷,協程避免了無意義的調度,由此可以提高性能(但也因此,程序員必須自己承擔調度的責任,同時,協程也失去了標準線程使用多CPU的能力)
(2)無需原子操作鎖定及同步的開銷
(3)方便切換控制流,簡化編程模型
(4)高并發+高擴展性+低成本:一個CPU支持上萬的協程都不是問題。所以很適合用于高并發處理。
協程的缺點:
(1)無法利用多核資源:協程的本質是個單線程,它不能同時將 單個CPU 的多個核用上,協程需要和進程配合才能運行在多CPU上.當然我們日常所編寫的絕大部分應用都沒有這個必要,除非是cpu密集型應用。
(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)#創建一個協程對象 g2=greenlet.greenlet(test2) g1.switch()#啟動協程/切換協程gevnet是協程之間的自動切換
?
import gevent def func1():print(12)gevent.sleep(2)print(56)def func2():print(34)gevent.sleep(1)print(78) t1=gevent.spawn(func1)#創建一個線程對象 t2=gevent.spawn(func2) print(t1) gevent.joinall([t1,t2])#添加線程對象,并運行線程
?
?
轉載于:https://www.cnblogs.com/Mr-l/p/10373862.html
總結
以上是生活随笔為你收集整理的python第10天(上)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: php 安装redis php扩展
- 下一篇: python测试开发django-1.开