首先值得說(shuō)明的是進(jìn)程和線程的概念,程序是數(shù)據(jù)和有序指令的結(jié)合,是一個(gè)靜態(tài)的概念,當(dāng)程序在計(jì)算機(jī)中運(yùn)行之后才有了動(dòng)態(tài)的概念,而進(jìn)程就是程序動(dòng)態(tài)概念。進(jìn)程是系統(tǒng)中分配資源的最小單位,一般情況下進(jìn)程之間是相互獨(dú)立的,多進(jìn)程之間是不能進(jìn)行數(shù)據(jù)共享的,在保護(hù)模式下,一個(gè)進(jìn)程掛了,其他進(jìn)程不會(huì)受到什么影響;線程是存在于進(jìn)程中的,作為最小調(diào)度和執(zhí)行的單位,較比進(jìn)程需要的系統(tǒng)資源少很多,切換效率更高,但是一旦線程掛了,所對(duì)應(yīng)的進(jìn)程也會(huì)隨之掛了,因此多進(jìn)程程序比多線程程序具有更好的程序健壯性。
總結(jié):無(wú)論多線程還是多進(jìn)程都不是完美的,需要根據(jù)實(shí)際情況選擇對(duì)應(yīng)的,如果在多核執(zhí)行機(jī)上建議使用多線程,而進(jìn)程則可以跨機(jī)器遷移。
def?run(name):
????print('hello,',?name)
????time.sleep(1)
????t?=?threading.Thread(target=run_thread,)
????t.start()
if?__name__?==?'__main__':
????for?i?in?range(10):
????????process?=?multiprocessing.Process(target=run,?args=('test',))
????????process.start()?#?啟動(dòng)進(jìn)程
????????process.join()?#?等待進(jìn)程結(jié)果
#?子進(jìn)程不會(huì)影響主進(jìn)程的全局變量
import?multiprocessing
import?time
import?os
h?=?['hello']??#?全局變量,主進(jìn)程與子進(jìn)程是并發(fā)執(zhí)行的,子進(jìn)程不能改變主進(jìn)程中全局變量的值
def?tt():
????datalist?=?[]
????datalist.append(1)
????datalist.append(2)
????datalist.append(3)
????time.sleep(3)
????print("son",?os.getpid(),?datalist)
if?__name__?==?"__main__":
????p?=?multiprocessing.Process(target=tt,?args=())
????p.start()
????#?p.join()??#?順序執(zhí)行
????print?h??#?全局變量不受影響
????h.append("a")
????h.append("b")
????h.append("c")
????print("parent",?os.getpid(),?h)
默認(rèn)情況下不同進(jìn)程的內(nèi)存是不能共享的,如果要實(shí)現(xiàn)進(jìn)程之間共享數(shù)據(jù),需要加入進(jìn)程中Queue,如下
from?multiprocessing?import?Process,?Queue
def?f(q):
????q.put([66666,?None,?'hello?word'])
if?__name__?==?'__main__':
????q?=?Queue()??#?把這個(gè)q傳給了子線程
????p?=?Process(target=f,?args=(q,))??#?子線程訪問(wèn)父線程的q
????p.start()
????print(q.get())
????p.join()
除了上面的Queue實(shí)現(xiàn)數(shù)據(jù)的共享還有Pipe, Manger()
from?multiprocessing?import?Manager,Pipe,Process,os,?Lock
def?t(d,l):
????d[os.getpid()]?=?os.getpid()
????l.append(os.getpid())
if?__name__?=='__main__':
????#?parent_cnn,?child_cnn?=?Pipe()??#?管道生成兩個(gè)實(shí)例
????with?Manager()?as?manager:
????????d?=?manager.dict()
????????l?=?manager.list(range(10))?#?聲明一個(gè)[0,1,2,3....,9]的列表
????????p_list?=?[]
????????for?i?in?range(5):
????????????p?=?Process(target=t,args=(d,l))
????????????#?p.daemon?=?True
????????????p.start()
????????????p_list.append(p)
????????for?j?in?p_list:
????????????j.join()
????????print?d?#?{11160:?11160,?11161:?11161,?11162:?11162,?11163:?11163,?11164:?11164}
????????print?l?#?[0,?1,?2,?3,?4,?5,?6,?7,?8,?9,?11160,?11161,?11162,?11163,?11164]
from?multiprocessing?import?Process,?Pipe
def?t(cnn):
????cnn.send('aaa')??#?發(fā)送數(shù)據(jù)
????cnn.send(['bbb',1,None])
????info?=?cnn.recv()??#?接受數(shù)據(jù)
????print?info
????cnn.close()
if?__name__?==?'__main__':
????parent_cnn,?child_cnn?=?Pipe()
????for?i?in?range(2):
????????p?=?Process(target=t,args=(child_cnn,))
????????p.start()
????????print?parent_cnn.recv()?
????????parent_cnn.send('vfdf')
????????p.join()
參考:https://www.onexing.cn