python進(jìn)程間數(shù)據(jù)交互的幾種實(shí)現(xiàn)方式
一 方法匯總
在 Python 進(jìn)程中,有幾種方法可以實(shí)現(xiàn)數(shù)據(jù)交互:
- 共享內(nèi)存:這是一種用于進(jìn)程間通信的高效方式。多個(gè)進(jìn)程可以訪問(wèn)同一個(gè)共享內(nèi)存區(qū)域,并在其中讀取和寫(xiě)入數(shù)據(jù)。
- 管道(Pipe):這是一種用于進(jìn)程間通信的基本方式。管道可以在兩個(gè)進(jìn)程之間傳遞數(shù)據(jù)。一個(gè)進(jìn)程將數(shù)據(jù)寫(xiě)入管道,另一個(gè)進(jìn)程從管道中讀取數(shù)據(jù)。
- 隊(duì)列(Queue):隊(duì)列也是一種進(jìn)程間通信的方式。一個(gè)進(jìn)程將數(shù)據(jù)放入隊(duì)列,另一個(gè)進(jìn)程從隊(duì)列中獲取數(shù)據(jù)。
- 套接字(Socket):套接字是一種用于網(wǎng)絡(luò)通信的方式,但它們也可以在同一臺(tái)計(jì)算機(jī)上進(jìn)行進(jìn)程間通信。每個(gè)套接字都有一個(gè)唯一的地址,進(jìn)程可以使用這個(gè)地址來(lái)發(fā)送和接收數(shù)據(jù)。
- 文件:進(jìn)程可以使用文件作為數(shù)據(jù)交換的方式。一個(gè)進(jìn)程將數(shù)據(jù)寫(xiě)入文件,另一個(gè)進(jìn)程從文件中讀取數(shù)據(jù)。
二 實(shí)際舉例
2.1 共享內(nèi)存
使用 multiprocessing.Value 可以創(chuàng)建進(jìn)程間共享的變量,下面是一個(gè)例子,創(chuàng)建了一個(gè)類(lèi)型為整數(shù)('i')的共享內(nèi)存變量 value,然后啟動(dòng) 10 個(gè)進(jìn)程去調(diào)用 func 函數(shù),該函數(shù)會(huì)將 value 的值加 1。最后輸出 value 的值,應(yīng)該是 10:
import multiprocessing
def func(value):
value.value += 1
if __name__ == '__main__':
value = multiprocessing.Value('i', 0)
processes = [multiprocessing.Process(target=func, args=(value,)) for _ in range(10)]
for process in processes:
process.start()
for process in processes:
process.join()
print(value.value) # 輸出 102.2 管道
使用 multiprocessing.Pipe 可以創(chuàng)建一個(gè)管道,兩個(gè)進(jìn)程可以通過(guò)這個(gè)管道互相傳遞數(shù)據(jù),下面是一個(gè)例子,創(chuàng)建了一個(gè)管道,其中 parent_conn 是父進(jìn)程持有的端口,child_conn 是子進(jìn)程持有的端口。然后啟動(dòng)兩個(gè)進(jìn)程,分別調(diào)用 sender 和 receiver 函數(shù)。sender 函數(shù)發(fā)送一條消息到管道中,receiver 函數(shù)從管道中接收消息并打印出來(lái):
import multiprocessing
def sender(conn):
conn.send('Hello, receiver')
def receiver(conn):
message = conn.recv()
print(message)
if __name__ == '__main__':
parent_conn, child_conn = multiprocessing.Pipe()
p1 = multiprocessing.Process(target=sender, args=(parent_conn,))
p2 = multiprocessing.Process(target=receiver, args=(child_conn,))
p1.start()
p2.start()
p1.join()
p2.join()2.3 隊(duì)列
使用 multiprocessing.Queue 可以創(chuàng)建一個(gè)進(jìn)程間共享的隊(duì)列,多個(gè)進(jìn)程可以通過(guò)這個(gè)隊(duì)列互相傳遞數(shù)據(jù),下面是一個(gè)例子,創(chuàng)建了一個(gè)進(jìn)程間共享的隊(duì)列 q,然后啟動(dòng)了四個(gè)進(jìn)程去調(diào)用 worker 函數(shù),該函數(shù)會(huì)從隊(duì)列中獲取數(shù)據(jù)并打印出來(lái)。主進(jìn)程向隊(duì)列中發(fā)送 10 個(gè)數(shù)值,每個(gè)進(jìn)程都會(huì)從隊(duì)列中獲取數(shù)據(jù)并進(jìn)行處理。當(dāng)主進(jìn)程發(fā)送完所有內(nèi)容后,向隊(duì)列中發(fā)送 N 個(gè) None 值(N 等于進(jìn)程數(shù)量),以通知各進(jìn)程退出:
import multiprocessing
def worker(q):
while True:
item = q.get()
if item is None:
break
print(item)
if __name__ == '__main__':
q = multiprocessing.Queue()
processes = [multiprocessing.Process(target=worker, args=(q,)) for _ in range(4)]
for process in processes:
process.start()
for i in range(10):
q.put(i)
for _ in range(len(processes)):
q.put(None)
for process in processes:
process.join()2.4 套接字
使用 Python 的 socket 模塊可以創(chuàng)建套接字,進(jìn)而實(shí)現(xiàn)網(wǎng)絡(luò)通信和進(jìn)程間通信。下面是一個(gè)簡(jiǎn)單的例子,創(chuàng)建了一個(gè)服務(wù)器進(jìn)程和一個(gè)客戶(hù)端進(jìn)程。服務(wù)器進(jìn)程監(jiān)聽(tīng)本機(jī)的 8888 端口,接收客戶(hù)端發(fā)來(lái)的數(shù)據(jù)并打印出來(lái);客戶(hù)端進(jìn)程連接服務(wù)器的 8888 端口,并向服務(wù)器發(fā)送一條消息。運(yùn)行上述代碼后,可以看到服務(wù)器進(jìn)程收到客戶(hù)端發(fā)送的消息并打印出來(lái):
import socket
def server():
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.bind(('127.0.0.1', 8888))
server_socket.listen(1)
conn, addr = server_socket.accept()
while True:
data = conn.recv(1024)
if not data:
break
print(data.decode())
conn.close()
server_socket.close()
def client():
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client_socket.connect(('127.0.0.1', 8888))
client_socket.sendall(b'Hello, server')
client_socket.close()
if __name__ == '__main__':
import multiprocessing
server_process = multiprocessing.Process(target=server)
client_process = multiprocessing.Process(target=client)
server_process.start()
client_process.start()
server_process.join()
client_process.join()2.5 文件
在 Python 中使用文件進(jìn)行進(jìn)程間通信也是比較常見(jiàn)的方式。下面是一個(gè)例子,創(chuàng)建了一個(gè)文件 test.txt,該文件包含了三行文本。然后啟動(dòng)兩個(gè)進(jìn)程去調(diào)用 worker 函數(shù),該函數(shù)會(huì)讀取文件內(nèi)容并打印出來(lái)。當(dāng)兩個(gè)進(jìn)程都完成任務(wù)后,主進(jìn)程結(jié)束。運(yùn)行上述代碼后,可以看到兩個(gè)進(jìn)程分別打印了 test.txt 文件的內(nèi)容:
import multiprocessing
def worker(file):
with open(file, 'r') as f:
for line in f:
print(line.rstrip())
if __name__ == '__main__':
filename = 'test.txt'
with open(filename, 'w') as f:
f.write('Line 1\n')
f.write('Line 2\n')
f.write('Line 3\n')
processes = [multiprocessing.Process(target=worker, args=(filename,)) for _ in range(2)]
for process in processes:
process.start()
for process in processes:
process.join()三 python子進(jìn)程傳數(shù)據(jù)到主進(jìn)程的方式
Python中有多種方式可以讓子進(jìn)程傳遞數(shù)據(jù)給主進(jìn)程。這里我列舉其中三種比較常用的方式:
- 使用隊(duì)列(Queue):隊(duì)列是多進(jìn)程編程中常用的通信工具,可以在多個(gè)進(jìn)程之間傳遞消息。在主進(jìn)程中初始化一個(gè)隊(duì)列對(duì)象,然后將其作為參數(shù)傳遞給子進(jìn)程,在子進(jìn)程中使用put()方法向隊(duì)列中添加數(shù)據(jù),主進(jìn)程可以使用get()方法獲取數(shù)據(jù)。
下面是一個(gè)使用隊(duì)列實(shí)現(xiàn)子進(jìn)程傳遞數(shù)據(jù)給主進(jìn)程的例子:
import multiprocessing as mp
def func(queue):
# 子進(jìn)程向隊(duì)列中添加數(shù)據(jù)
queue.put("hello from child process")
if __name__ == '__main__':
# 初始化一個(gè)隊(duì)列
queue = mp.Queue()
# 創(chuàng)建一個(gè)子進(jìn)程并將隊(duì)列作為參數(shù)傳遞給它
p = mp.Process(target=func, args=(queue,))
p.start()
# 主進(jìn)程從隊(duì)列中獲取數(shù)據(jù)
data = queue.get()
print(data)- 使用管道(Pipe):管道也可以在多個(gè)進(jìn)程之間傳遞消息,不同于隊(duì)列的是它只支持兩個(gè)進(jìn)程之間的通信。在主進(jìn)程中創(chuàng)建一個(gè)管道,然后將其作為參數(shù)傳遞給子進(jìn)程,在子進(jìn)程中使用send()方法向管道中發(fā)送數(shù)據(jù),主進(jìn)程可以使用recv()方法接收數(shù)據(jù)。
下面是一個(gè)使用管道實(shí)現(xiàn)子進(jìn)程傳遞數(shù)據(jù)給主進(jìn)程的例子:
import multiprocessing as mp
def func(pipe):
# 子進(jìn)程向管道中發(fā)送數(shù)據(jù)
pipe.send("hello from child process")
if __name__ == '__main__':
# 創(chuàng)建一個(gè)管道
parent_conn, child_conn = mp.Pipe()
# 創(chuàng)建一個(gè)子進(jìn)程并將管道作為參數(shù)傳遞給它
p = mp.Process(target=func, args=(child_conn,))
p.start()
# 主進(jìn)程從管道中接收數(shù)據(jù)
data = parent_conn.recv()
print(data)- 使用共享內(nèi)存(Value和Array):共享內(nèi)存可以讓多個(gè)進(jìn)程之間共享同一塊內(nèi)存區(qū)域,這樣就可以避免進(jìn)程之間頻繁地復(fù)制數(shù)據(jù)。在主進(jìn)程中使用Value或Array創(chuàng)建一個(gè)共享內(nèi)存對(duì)象,然后將其作為參數(shù)傳遞給子進(jìn)程,在子進(jìn)程中可以直接修改共享內(nèi)存對(duì)象中的值,主進(jìn)程也可以直接讀取共享內(nèi)存對(duì)象中的值。
下面是一個(gè)使用共享內(nèi)存實(shí)現(xiàn)子進(jìn)程傳遞數(shù)據(jù)給主進(jìn)程的例子:
import multiprocessing as mp
def func(val):
# 子進(jìn)程修改共享內(nèi)存對(duì)象中的值
val.value = 123
if __name__ == '__main__':
# 創(chuàng)建一個(gè)共享內(nèi)存對(duì)象
val = mp.Value('i', 0)
# 創(chuàng)建一個(gè)子進(jìn)程并將共享內(nèi)存對(duì)象作為參數(shù)傳遞給它
p = mp.Process(target=func, args=(val,))
p.start()
# 主進(jìn)程讀取共享內(nèi)存對(duì)象中的值
print(val.value)到此這篇關(guān)于python進(jìn)程數(shù)據(jù)交互的幾種實(shí)現(xiàn)方式的文章就介紹到這了,更多相關(guān)python進(jìn)程數(shù)據(jù)交互內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
pandas把所有大于0的數(shù)設(shè)置為1的方法
今天小編就為大家分享一篇pandas把所有大于0的數(shù)設(shè)置為1的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2019-01-01
Python散列表(Hash Table)的實(shí)現(xiàn)示例
散列表是一種常用于實(shí)現(xiàn)關(guān)聯(lián)數(shù)組或映射的數(shù)據(jù)結(jié)構(gòu),本文我們將深入講解Python中的散列表,包括散列函數(shù)、沖突解決方法、散列表的實(shí)現(xiàn)和應(yīng)用場(chǎng)景,感興趣的可以了解一下2024-01-01
Django實(shí)現(xiàn)在線(xiàn)無(wú)水印抖音視頻下載(附源碼及地址)
該項(xiàng)目功能簡(jiǎn)單,完全復(fù)制SaveTweetVedio的項(xiàng)目。用戶(hù)觀看抖音視頻時(shí)選擇復(fù)制視頻鏈接,輸入到下載輸入欄,即可下載無(wú)水印視頻,還可掃描二維碼手機(jī)上預(yù)覽。親測(cè)成功。2021-05-05
python 還原梯度下降算法實(shí)現(xiàn)一維線(xiàn)性回歸
這篇文章主要介紹了python 還原梯度下降算法實(shí)現(xiàn)一維線(xiàn)性回歸,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-10-10
Python 兩個(gè)列表的差集、并集和交集實(shí)現(xiàn)代碼
這篇文章主要介紹了Python 兩個(gè)列表的差集、并集和交集實(shí)現(xiàn)代碼,需要的朋友可以參考下2016-09-09
opencv python 圖片讀取與顯示圖片窗口未響應(yīng)問(wèn)題的解決
這篇文章主要介紹了opencv python 圖片讀取與顯示圖片窗口未響應(yīng)問(wèn)題的解決,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-04-04
Python編程使用NLTK進(jìn)行自然語(yǔ)言處理詳解
這篇文章主要介紹了Python編程使用NLTK進(jìn)行自然語(yǔ)言處理詳解,涉及了nltk和開(kāi)發(fā)環(huán)境的簡(jiǎn)單介紹,以及SentencesSegment,SentencesSegment等內(nèi)容,具有一定參考價(jià)值,需要的朋友可以了解下。2017-11-11
用python實(shí)現(xiàn)名片管理系統(tǒng)
這篇文章主要為大家詳細(xì)介紹了用python實(shí)現(xiàn)名片管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-06-06

