python中的多線程其實並不是真正的多線程,如果想要充分地使用多核CPU的資源,在python中大部分情況需要使用多進程。 進程與線程的使用有很多相似之處,有關線程方面的知識請參考https://www.cnblogs.com/sfencs-hcy/p/9721362.html multiproc ...
python中的多線程其實並不是真正的多線程,如果想要充分地使用多核CPU的資源,在python中大部分情況需要使用多進程。
進程與線程的使用有很多相似之處,有關線程方面的知識請參考https://www.cnblogs.com/sfencs-hcy/p/9721362.html
multiprocessing模塊
1.進程的創建
import multiprocessing def func(msg): print(msg) print("這是一個進程") if __name__=="__main__": p=multiprocessing.Process(target=func,args=("hello world",)) p.start()
以繼承類的方式創建進程
import multiprocessing class Myprocessing(multiprocessing.Process): def __init__(self,name,age): multiprocessing.Process.__init__(self) self.name=name self.age=age def run(self): #這裡是將threading.Thread中的run方法進行了重載 print("%s is %d"%(self.name,self.age)) if __name__=="__main__": t=Myprocessing("sfencs",19) t.start()
2.進程的並行
import multiprocessing import time class Myprocessing(multiprocessing.Process): def __init__(self,name,age,second): multiprocessing.Process.__init__(self) self.name=name self.second=second self.age=age def run(self): print(self.name) time.sleep(self.second) print(self.age) if __name__=="__main__": time_begin=time.time() p1=Myprocessing("sfencs",19,2) p2=Myprocessing("Tom",25,5) p1.start() p2.start() p1.join() p2.join() time_end=time.time() print(time_end-time_begin) ''' Tom 19 25 5.198107481002808 '''
join的用法和線程相同
3.守護進程
守護進程與守護線程的原理相同,只不過設置守護進程的方式為p.daemon=True
4.lock
lock的作用同多線程,實現方式有兩種
import multiprocessing def func2(lock,f): with lock: fs=open(f,'a+') fs.write('Lockd acquired via with\n') fs.close() def func1(lock,f): lock.acquire() fs=open(f,'a+') fs.write('Lock acquired directly\n') fs.close() lock.release() if __name__=="__main__": lock=multiprocessing.Lock() f = "file.txt" p1=multiprocessing.Process(target=func2,args=(lock,f,)) p2=multiprocessing.Process(target=func1,args=(lock,f,)) p1.start() p2.start() p1.join() p2.join()
與線程不同的是,這裡lock是以參數方式傳遞,因為不同的進程並不能共用資源
5.Semaphore
用來控制對共用資源的最大訪問數量
import multiprocessing import time def func(s, i): s.acquire() print(multiprocessing.current_process().name + "acquire"); time.sleep(2) print(multiprocessing.current_process().name + "release\n"); s.release() if __name__ == "__main__": s = multiprocessing.Semaphore(2) for i in range(5): p = multiprocessing.Process(target = func, args=(s, 2)) p.start()
6.event與線程用法相同
7.隊列
有一個專門屬於多進程的隊列multiprocessing.Queue
import multiprocessing def writer(q): q.put("hello world") def reader(q): print(q.get()) if __name__ == "__main__": q = multiprocessing.Queue() pwriter=multiprocessing.Process(target=writer,args=(q,)) preader = multiprocessing.Process(target=reader, args=(q,)) pwriter.start() preader.start()
8.管道pipe
Pipe方法返回(conn1, conn2)代表一個管道的兩個端。Pipe方法有duplex參數,如果duplex參數為True(預設值),那麼這個管道是全雙工模式,也就是說conn1和conn2均可收發。duplex為False,conn1只負責接受消息,conn2只負責發送消息。
import multiprocessing def sender(p): p.send("hello world") def receiver(p): print(p.recv()) if __name__ == "__main__": p = multiprocessing.Pipe() psender=multiprocessing.Process(target=sender,args=(p[0],)) preceiver = multiprocessing.Process(target=receiver, args=(p[1],)) psender.start() preceiver.start()
9.manager
manager實現進程之間數據共用
import multiprocessing def func(list1,d,i): list1[i]=i d["a"]=i if __name__ == "__main__": with multiprocessing.Manager() as manager: list1=manager.list(range(5,10)) d=manager.dict() plist=[] for i in range(5): p=multiprocessing.Process(target=func,args=(list1,d,i)) plist.append(p) p.start() for i in plist: i.join() print(list1) print(d)
未完