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:UsersAdministratorAppDataRoamingTypora	ypora-user-imagesimage-20211215185302558.png)]

共享内存

1.通信原理

在内存中开辟一块空间,进程可以写入内容和读取内容完成通信,但是每次写入内容会覆盖之前内容

2.实现方法

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-A5RVhKd1-1639571874328)(C:UsersAdministratorAppDataRoamingTypora	ypora-user-imagesimage-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:UsersAdministratorAppDataRoamingTypora	ypora-user-imagesimage-20211215203718835.png)]

到此这篇关于python中进程间通信详细介绍的文章就介绍到这了,更多相关python进程间通信内容请搜索云海天教程以前的文章或继续浏览下面的相关文章希望大家以后多多支持云海天教程!