python中進程間通信詳細介紹

進程間通信(IPC)

必要性

進程間空間獨立,資源不共享,此時在需要進程間數據傳輸時就需要特定的手段進行數據通信

常用進程間通信方法

管道 消息隊列 共享內存 型號 信號量 套接字

管道通信(Pipe)

1.通信原理

在內存中開辟管道空間,生成管道操作對象,多個進程使用同一個管道對象進行讀寫即可實現通信

代碼演示(windows 無效 linux 可用)

"""
pipe.py 管道通信
註意
1. multiprocessing 中管道通信隻能用於有親緣關系進程中
2. 管道對象在父進程中創建,子進程通過父進程獲取
"""
from multiprocessing import Process, Pipe

# 創建 管道
fd1, fd2 = Pipe()
def app1():
    print('1 啟動應用1,請登錄')
    print('2 請求app2授權')
    fd1.send('app1 請求登錄')
    data = fd1.recv()
    print('5 ??',data)
    if data:
        print('6 登錄成功:', data)


def app2():
    print('2.5')
    # 阻塞等待讀取管道內容
    data = fd2.recv()
    print('3 app2', data)
    fd2.send(('Dave', '123'))
    print('4 app2,發送完畢')


if __name__ == '__main__':
    print(-5)
    p1 = Process(target=app1)
    print(-4)
    p2 = Process(target=app2)
    print(-3)
    p1.start()
    print(-2)
    p2.start()
    print(-1)
    p1.join()
    print(0)
    p2.join()
    print('運行結束')
"""
運行結果
(base) [root@VM-0-12-centos pipe]# python pipe.py
-5
-4
-3
-2
-1
1 啟動應用1,請登錄
2 請求app2授權
2.5
3 app2 app1 請求登錄
4 app2,發送完畢
5 ?? ('Dave', '123')
6 登錄成功: ('Dave', '123')
0
運行結束

"""

消息隊列

在內存中建立隊列模型,進程通過隊列將消息存入,或者從隊列取出完成 進程間通信

2. 實現方法

"""
quque_test.py 消息隊列演示
註意: 消息隊列符合先進先出原則
"""

# 創建消息隊列
from multiprocessing import Queue, Process
from random import randint

# 以下模擬 雙色球
# 創建消息隊列
q = Queue(5)

def handle():
    print(5)
    for i in range(6):
        q.put(randint(1, 33))
    q.put(randint(1, 16))

def request():
    print(6)
    l = [q.get() for i in range(6)]
    l.sort()
    l.append(q.get())
    print(7,l)

if __name__ == '__main__':
    print(0)
    p1 = Process(target=handle)
    print(1)
    p2 = Process(target=request)
    print(2)
    p1.start()
    print(3)
    p2.start()
    print(4)
    p1.join()
    p2.join()
    print(8)
    print('程序結束')

控制臺輸出 linux (windows無效)

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-cXtoSmyN-1639571874327)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20211215185302558.png)]

共享內存

1.通信原理

在內存中開辟一塊空間,進程可以寫入內容和讀取內容完成通信,但是每次寫入內容會覆蓋之前內容

2.實現方法

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-A5RVhKd1-1639571874328)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20211215185911875.png)]

value ,array

from multiprocessing import Value,Array

obj = Value(ctype,data)
功能: 開辟共享內存
參數: ctype 表示共享內存空間類型 'i' 'f' 'c'
	data 共享內存空間初始數據
返回值: 共享內存對象

obj.value 對象屬性的修改查看即對共享內存讀寫

obj = Array(ctype,data)
功能: 開辟共享內存
參數: ctype 表示共享內存空間類型 'i' 'f' 'c'
	data 整數表示開辟空間的大小,其數據表示開辟空間
返回值: 共享內存對象

Array共享內存讀寫:通過遍歷obj可以得到每個值,直接通過索引可以修改

* 可以使用obj.value 直接打印共享內存中的字節串

value 代碼 演示

"""
value.py 開辟單一共享內存空間
註意:共享內存隻能有一個值
"""

from multiprocessing import Value,Array,Process


import time
import random
ctype = 'i'
data = 5000
# 創建共享內存
money = Value(ctype,data)

# 操作共享內存
def man():
    for i in range(30):
        time.sleep(0.1)
        money.value += random.randint(1,1000)
        print('man',money.value)

def girl():
    for i in range(30):
        time.sleep(0.1)
        money.value -= random.randint(1,800)
        print('girl', money.value)

if __name__ == '__main__':
    p1 = Process(target=man)
    p2 = Process(target=girl)
    p1.start()
    p2.start()
    p1.join()
    p2.join()
    print('程序結束',money.value)

array 代碼演示

"""
array.py 開辟單一共享內存空間
註意:共享內存隻能有一個值
"""

from multiprocessing import Array,Process


ctype = 'i'
data = [1,2,3,4]
# 創建共享內存
# shm = Array(ctype,data)

# 表示初始值 [0,0,0,0,0]
shm = Array(ctype,5)


def fun():
    for i in shm:
        print(i)
    shm[1] = 1000
if __name__ == '__main__':
    p1 = Process(target=fun)
    p1.start()
    p1.join()
    print('程序結束',shm[1])

信號量(信號燈集)

1.通信原理

給定一個數量多多個進程可見,多個進程都可以操作該數增減,並根據數量值決定自己的行為

2. 實現方法

from multiprocessing import Semaphore

sem = Semaphore(num)
功能: 創建信號量對象
參數: 信號量的初始值
返回值: 信號量對象

sem.acquire() 信號量減1 當信號量為0時阻塞
sem.release() 信號量加1
sem.get_value() 獲取信號量數量

3.代碼演示

"""
信號量.py 信號量演示
思路: 信號量數量相當於資源,執行任務必須消耗資源
"""
import os
from multiprocessing import Semaphore
from multiprocessing import Process
from time import sleep

num = 3
sem = Semaphore(num)


# 任務函數
def handle():
    sem.acquire()  # sem -1
    print("%s 開始執行任務" % os.getpid())
    sleep(3)
    print("%s 執行任務完畢" % os.getpid())
    sem.release()  # sem +1


if __name__ == '__main__':
    ths = []
    for i in range(10):
        p = Process(target=handle)
        p.start()
        ths.append(p)

    for p in ths:
        p.join()
    print('程序結束')

控制臺運行結果

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-BjnjTpgF-1639571874329)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20211215203718835.png)]

到此這篇關於python中進程間通信詳細介紹的文章就介紹到這瞭,更多相關python進程間通信內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!

推薦閱讀: