python進程間數據交互的幾種實現方式
一 方法匯總
在 Python 進程中,有幾種方法可以實現數據交互:
- 共享內存:這是一種用于進程間通信的高效方式。多個進程可以訪問同一個共享內存區(qū)域,并在其中讀取和寫入數據。
- 管道(Pipe):這是一種用于進程間通信的基本方式。管道可以在兩個進程之間傳遞數據。一個進程將數據寫入管道,另一個進程從管道中讀取數據。
- 隊列(Queue):隊列也是一種進程間通信的方式。一個進程將數據放入隊列,另一個進程從隊列中獲取數據。
- 套接字(Socket):套接字是一種用于網絡通信的方式,但它們也可以在同一臺計算機上進行進程間通信。每個套接字都有一個唯一的地址,進程可以使用這個地址來發(fā)送和接收數據。
- 文件:進程可以使用文件作為數據交換的方式。一個進程將數據寫入文件,另一個進程從文件中讀取數據。
二 實際舉例
2.1 共享內存
使用 multiprocessing.Value 可以創(chuàng)建進程間共享的變量,下面是一個例子,創(chuàng)建了一個類型為整數('i')的共享內存變量 value,然后啟動 10 個進程去調用 func 函數,該函數會將 value 的值加 1。最后輸出 value 的值,應該是 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)建一個管道,兩個進程可以通過這個管道互相傳遞數據,下面是一個例子,創(chuàng)建了一個管道,其中 parent_conn 是父進程持有的端口,child_conn 是子進程持有的端口。然后啟動兩個進程,分別調用 sender 和 receiver 函數。sender 函數發(fā)送一條消息到管道中,receiver 函數從管道中接收消息并打印出來:
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)建一個進程間共享的隊列,多個進程可以通過這個隊列互相傳遞數據,下面是一個例子,創(chuàng)建了一個進程間共享的隊列 q,然后啟動了四個進程去調用 worker 函數,該函數會從隊列中獲取數據并打印出來。主進程向隊列中發(fā)送 10 個數值,每個進程都會從隊列中獲取數據并進行處理。當主進程發(fā)送完所有內容后,向隊列中發(fā)送 N 個 None 值(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)建套接字,進而實現網絡通信和進程間通信。下面是一個簡單的例子,創(chuàng)建了一個服務器進程和一個客戶端進程。服務器進程監(jiān)聽本機的 8888 端口,接收客戶端發(fā)來的數據并打印出來;客戶端進程連接服務器的 8888 端口,并向服務器發(fā)送一條消息。運行上述代碼后,可以看到服務器進程收到客戶端發(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,該文件包含了三行文本。然后啟動兩個進程去調用 worker 函數,該函數會讀取文件內容并打印出來。當兩個進程都完成任務后,主進程結束。運行上述代碼后,可以看到兩個進程分別打印了 test.txt 文件的內容:
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子進程傳數據到主進程的方式
Python中有多種方式可以讓子進程傳遞數據給主進程。這里我列舉其中三種比較常用的方式:
- 使用隊列(Queue):隊列是多進程編程中常用的通信工具,可以在多個進程之間傳遞消息。在主進程中初始化一個隊列對象,然后將其作為參數傳遞給子進程,在子進程中使用put()方法向隊列中添加數據,主進程可以使用get()方法獲取數據。
下面是一個使用隊列實現子進程傳遞數據給主進程的例子:
import multiprocessing as mp
def func(queue):
# 子進程向隊列中添加數據
queue.put("hello from child process")
if __name__ == '__main__':
# 初始化一個隊列
queue = mp.Queue()
# 創(chuàng)建一個子進程并將隊列作為參數傳遞給它
p = mp.Process(target=func, args=(queue,))
p.start()
# 主進程從隊列中獲取數據
data = queue.get()
print(data)- 使用管道(Pipe):管道也可以在多個進程之間傳遞消息,不同于隊列的是它只支持兩個進程之間的通信。在主進程中創(chuàng)建一個管道,然后將其作為參數傳遞給子進程,在子進程中使用send()方法向管道中發(fā)送數據,主進程可以使用recv()方法接收數據。
下面是一個使用管道實現子進程傳遞數據給主進程的例子:
import multiprocessing as mp
def func(pipe):
# 子進程向管道中發(fā)送數據
pipe.send("hello from child process")
if __name__ == '__main__':
# 創(chuàng)建一個管道
parent_conn, child_conn = mp.Pipe()
# 創(chuàng)建一個子進程并將管道作為參數傳遞給它
p = mp.Process(target=func, args=(child_conn,))
p.start()
# 主進程從管道中接收數據
data = parent_conn.recv()
print(data)- 使用共享內存(Value和Array):共享內存可以讓多個進程之間共享同一塊內存區(qū)域,這樣就可以避免進程之間頻繁地復制數據。在主進程中使用Value或Array創(chuàng)建一個共享內存對象,然后將其作為參數傳遞給子進程,在子進程中可以直接修改共享內存對象中的值,主進程也可以直接讀取共享內存對象中的值。
下面是一個使用共享內存實現子進程傳遞數據給主進程的例子:
import multiprocessing as mp
def func(val):
# 子進程修改共享內存對象中的值
val.value = 123
if __name__ == '__main__':
# 創(chuàng)建一個共享內存對象
val = mp.Value('i', 0)
# 創(chuàng)建一個子進程并將共享內存對象作為參數傳遞給它
p = mp.Process(target=func, args=(val,))
p.start()
# 主進程讀取共享內存對象中的值
print(val.value)到此這篇關于python進程數據交互的幾種實現方式的文章就介紹到這了,更多相關python進程數據交互內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
opencv python 圖片讀取與顯示圖片窗口未響應問題的解決
這篇文章主要介紹了opencv python 圖片讀取與顯示圖片窗口未響應問題的解決,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-04-04

