python進程間數(shù)據(jù)交互的幾種實現(xiàn)方式
一 方法匯總
在 Python 進程中,有幾種方法可以實現(xiàn)數(shù)據(jù)交互:
- 共享內(nèi)存:這是一種用于進程間通信的高效方式。多個進程可以訪問同一個共享內(nèi)存區(qū)域,并在其中讀取和寫入數(shù)據(jù)。
- 管道(Pipe):這是一種用于進程間通信的基本方式。管道可以在兩個進程之間傳遞數(shù)據(jù)。一個進程將數(shù)據(jù)寫入管道,另一個進程從管道中讀取數(shù)據(jù)。
- 隊列(Queue):隊列也是一種進程間通信的方式。一個進程將數(shù)據(jù)放入隊列,另一個進程從隊列中獲取數(shù)據(jù)。
- 套接字(Socket):套接字是一種用于網(wǎng)絡(luò)通信的方式,但它們也可以在同一臺計算機上進行進程間通信。每個套接字都有一個唯一的地址,進程可以使用這個地址來發(fā)送和接收數(shù)據(jù)。
- 文件:進程可以使用文件作為數(shù)據(jù)交換的方式。一個進程將數(shù)據(jù)寫入文件,另一個進程從文件中讀取數(shù)據(jù)。
二 實際舉例
2.1 共享內(nèi)存
使用 multiprocessing.Value 可以創(chuàng)建進程間共享的變量,下面是一個例子,創(chuàng)建了一個類型為整數(shù)('i')的共享內(nèi)存變量 value,然后啟動 10 個進程去調(diào)用 func 函數(shù),該函數(shù)會將 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)建一個管道,兩個進程可以通過這個管道互相傳遞數(shù)據(jù),下面是一個例子,創(chuàng)建了一個管道,其中 parent_conn 是父進程持有的端口,child_conn 是子進程持有的端口。然后啟動兩個進程,分別調(diào)用 sender 和 receiver 函數(shù)。sender 函數(shù)發(fā)送一條消息到管道中,receiver 函數(shù)從管道中接收消息并打印出來:
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 隊列
使用 multiprocessing.Queue 可以創(chuàng)建一個進程間共享的隊列,多個進程可以通過這個隊列互相傳遞數(shù)據(jù),下面是一個例子,創(chuàng)建了一個進程間共享的隊列 q,然后啟動了四個進程去調(diào)用 worker 函數(shù),該函數(shù)會從隊列中獲取數(shù)據(jù)并打印出來。主進程向隊列中發(fā)送 10 個數(shù)值,每個進程都會從隊列中獲取數(shù)據(jù)并進行處理。當(dāng)主進程發(fā)送完所有內(nèi)容后,向隊列中發(fā)送 N 個 None 值(N 等于進程數(shù)量),以通知各進程退出:
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)建套接字,進而實現(xiàn)網(wǎng)絡(luò)通信和進程間通信。下面是一個簡單的例子,創(chuàng)建了一個服務(wù)器進程和一個客戶端進程。服務(wù)器進程監(jiān)聽本機的 8888 端口,接收客戶端發(fā)來的數(shù)據(jù)并打印出來;客戶端進程連接服務(wù)器的 8888 端口,并向服務(wù)器發(fā)送一條消息。運行上述代碼后,可以看到服務(wù)器進程收到客戶端發(fā)送的消息并打印出來:
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 中使用文件進行進程間通信也是比較常見的方式。下面是一個例子,創(chuàng)建了一個文件 test.txt,該文件包含了三行文本。然后啟動兩個進程去調(diào)用 worker 函數(shù),該函數(shù)會讀取文件內(nèi)容并打印出來。當(dāng)兩個進程都完成任務(wù)后,主進程結(jié)束。運行上述代碼后,可以看到兩個進程分別打印了 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子進程傳數(shù)據(jù)到主進程的方式
Python中有多種方式可以讓子進程傳遞數(shù)據(jù)給主進程。這里我列舉其中三種比較常用的方式:
- 使用隊列(Queue):隊列是多進程編程中常用的通信工具,可以在多個進程之間傳遞消息。在主進程中初始化一個隊列對象,然后將其作為參數(shù)傳遞給子進程,在子進程中使用put()方法向隊列中添加數(shù)據(jù),主進程可以使用get()方法獲取數(shù)據(jù)。
下面是一個使用隊列實現(xiàn)子進程傳遞數(shù)據(jù)給主進程的例子:
import multiprocessing as mp
def func(queue):
# 子進程向隊列中添加數(shù)據(jù)
queue.put("hello from child process")
if __name__ == '__main__':
# 初始化一個隊列
queue = mp.Queue()
# 創(chuàng)建一個子進程并將隊列作為參數(shù)傳遞給它
p = mp.Process(target=func, args=(queue,))
p.start()
# 主進程從隊列中獲取數(shù)據(jù)
data = queue.get()
print(data)- 使用管道(Pipe):管道也可以在多個進程之間傳遞消息,不同于隊列的是它只支持兩個進程之間的通信。在主進程中創(chuàng)建一個管道,然后將其作為參數(shù)傳遞給子進程,在子進程中使用send()方法向管道中發(fā)送數(shù)據(jù),主進程可以使用recv()方法接收數(shù)據(jù)。
下面是一個使用管道實現(xiàn)子進程傳遞數(shù)據(jù)給主進程的例子:
import multiprocessing as mp
def func(pipe):
# 子進程向管道中發(fā)送數(shù)據(jù)
pipe.send("hello from child process")
if __name__ == '__main__':
# 創(chuàng)建一個管道
parent_conn, child_conn = mp.Pipe()
# 創(chuàng)建一個子進程并將管道作為參數(shù)傳遞給它
p = mp.Process(target=func, args=(child_conn,))
p.start()
# 主進程從管道中接收數(shù)據(jù)
data = parent_conn.recv()
print(data)- 使用共享內(nèi)存(Value和Array):共享內(nèi)存可以讓多個進程之間共享同一塊內(nèi)存區(qū)域,這樣就可以避免進程之間頻繁地復(fù)制數(shù)據(jù)。在主進程中使用Value或Array創(chuàng)建一個共享內(nèi)存對象,然后將其作為參數(shù)傳遞給子進程,在子進程中可以直接修改共享內(nèi)存對象中的值,主進程也可以直接讀取共享內(nèi)存對象中的值。
下面是一個使用共享內(nèi)存實現(xiàn)子進程傳遞數(shù)據(jù)給主進程的例子:
import multiprocessing as mp
def func(val):
# 子進程修改共享內(nèi)存對象中的值
val.value = 123
if __name__ == '__main__':
# 創(chuàng)建一個共享內(nèi)存對象
val = mp.Value('i', 0)
# 創(chuàng)建一個子進程并將共享內(nèi)存對象作為參數(shù)傳遞給它
p = mp.Process(target=func, args=(val,))
p.start()
# 主進程讀取共享內(nèi)存對象中的值
print(val.value)到此這篇關(guān)于python進程數(shù)據(jù)交互的幾種實現(xiàn)方式的文章就介紹到這了,更多相關(guān)python進程數(shù)據(jù)交互內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
使用python將csv數(shù)據(jù)導(dǎo)入mysql數(shù)據(jù)庫
這篇文章主要為大家詳細介紹了如何使用python將csv數(shù)據(jù)導(dǎo)入mysql數(shù)據(jù)庫,文中的示例代碼講解詳細,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2024-05-05
Python實現(xiàn)葵花8號衛(wèi)星數(shù)據(jù)自動下載實例
這篇文章主要為大家介紹了Python實現(xiàn)葵花8號衛(wèi)星數(shù)據(jù)自動下載實例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2022-10-10
PyQt5實現(xiàn)將Matplotlib圖像嵌入到Scoll Area中顯示滾動條效果
我想知道是否有一種方法可以在matplotlib上顯示滾動條(水平或垂直),顯示包含多個子槽(sublot2grid)的頁面(plt.show).下面就通過本文給大家分享PyQt5實現(xiàn)將Matplotlib圖像嵌入到Scoll Area中顯示滾動條效果,對PyQt5 Matplotlib圖像嵌入相關(guān)知識感興趣的的朋友一起看看吧2021-05-05
使用Django和Ansible實現(xiàn)自動化部署方式
這篇文章主要介紹了使用Django和Ansible實現(xiàn)自動化部署方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2025-05-05

