多線程的數(shù)據(jù)共享

首先值得說(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

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容