人工智能(PythonNet)—— 进程间通信(管道、消息队列、共享内存、信号、信号量、套接字)

一、进程间通信

        进程间通信(IPC,InterProcess Communication)是指在不同进程之间传播或交换信息。

        由于每个进程的空间是互相独立的,进程之间无法互相直接获取彼此的资源,故引入进程间通信来实现进程间的资源交互。

        进程间通信方法:管道、消息队列、共享内存、信号、信号量、套接字。

        补充:文件类型(查看方法:ls -l 或 ll)
                b(块设备文件)
                c(字符设备文件)
                d(文件夹)   
                - (普通文件)
                l (链接文件)    link
                s  套接字文件
                p  管道文件

二、管道通信   Pipe

        在内存中开辟一段空间,形成管道结构,管道对多个进程可见,进程可以对管道进行读写操作,实现多进程之间的通信。

        from multiprocess import Pipe  # 导入库

1、Pipe函数

        fd1,fd2 = Pipe(duplex = True)
        功能:创建一个管道
        参数:默认为双向管道
                    如果设置为False,则为单向管道
        返回值:返回两个管道流对象,表示管道的两端
                      如果双向管道,fd1 fd2都可以进行读写操作
                      如果是单向管道,则fd1只可读,fd2只可写

        fd.recv()
        功能:从管道读取内容(接收消息)
        参数:无
        返回值:读到的内容(接收消息)
                说明:如果管道无内容则阻塞

        fd.send(data)
        功能: 向管道写入内容(发送消息)
        参数: 要发送的内容
                 说明:如果没有接收端则管道破裂

2、示例

from multiprocessing import Process,Pipe 
import os,time 

#如果参数为False则fd1只能recv  fd2只能send
# fd1,fd2 = Pipe(False)

#创建一个双向管道
fd1,fd2 = Pipe()
# fd1.close()

def fun(name):
    time.sleep(3)
    #发字符串到管道
    fd2.send("hello " + str(name))
    print(os.getppid(),"----",os.getpid())

jobs = []
for i in range(5):
    p = Process(target = fun,args = (i,))
    jobs.append(p)
    p.start() 

#接收子进程发送的消息
for i in range(5):
    data = fd1.recv()
    print(data) 

for i in jobs:
    i.join()

三、消息队列 Queue

        队列存取规则: 先进先出

        在内存中开辟队列结构空间,多个进程可以向队列投放消息,在取出的时候按照存入顺序取出;任何拥有队列的进程都可以存取消息

1、Queue函数

        创建队列
        q = Queue(maxsize = 0)
        功能 : 创建队列
        参数 : maxsize  默认为0,表示根据系统分配空间存储消息
                                   如果传入一个正整数,表示最多存放多少条消息
        返回 : 消息队列对象

        q.put(data, [block, timeout])
        功能: 存放消息
        参数: data        存入的消息 (python数据类型)
                   block       默认为True表示当队列满的时候阻塞
                                   设置为False则表示非阻塞
                   timeout   当block为True表示超时时间

        data = q.get([block, timeout])
        功能 : 取出消息
        参数 : block     默认为True 当队列空时阻塞
                                  设置为False表示非阻塞
                    timeout  当block为True时表示超时时间
        返回值 : 返回获取的消息

        q.full()   判断队列是否为满
        q.empty()  判断队列是否为空
        q.qsize()  判断当前队列有多少消息
        q.close()  关闭队列

2、示例

        a、函数
from  multiprocessing import Queue 
from time import sleep
#创建队列
q = Queue(3) 

q.put(1)
print(q.full())
q.put(2)
q.put(3)
print(q.full())

# 设置超时事件为3sec
# q.put(4,True,3)

print(q.get())
print("队列中还有%d条消息"%q.qsize())
print(q.empty())
q.close() #关闭队列
        b、管道收发
from multiprocessing import Process,Queue 
import time 

#创建消息队列
q = Queue()

def fun1():
    time.sleep(1)
    q.put("我是进程1")

def fun2():
    time.sleep(2)
    print("取消息:",q.get())

p1 = Process(target = fun1)
p2 = Process(target = fun2)
p1.start()
p2.start()

p1.join()
p2.join()

四、共享内存

        在内存中开辟一段空间,存储数据,对多个进程可见。每次写入共享内存中的数据会覆盖之前的内容。由于对内存格式化较少,所以存取速度快。

        from multiprocessing import Value,Array

1、函数

        obj = Value(ctype,obj)
        功能:开辟共享内存空间
        参数:ctype   字符串  要转变的c的数据类型(对照ctype表)
                    obj   共享内存的初始化数据
        返回:返回一个共享内存对象
                补充:obj.value  表示共享内存中的值。对其修改或者使用即可

        obj = Array(ctype,obj)
        功能: 开辟共享内存
        参数: ctype    要转化的c的类型
                   obj        列表,表示要存入的数据,要求列表中数类型一致
                                正整数,表示开辟一个多大的序列空间
        返回值:返回一个共享内存对象
                补充:正常操作数值,读取和赋值

2、数据类型(ctype对照表)

Type code C Type Python Type Minimum size in bytes Notes
'b' signed char int 1  
'B' unsigned char int 1  
'u' Py_UNICODE Unicode character 2 (1)
'h' signed short int 2  
'H' unsigned short int 2  
'i' signed int int 2  
'I' unsigned int int 2  
'l' signed long int 4  
'L' unsigned long int 4  
'q' signed long long int 8 (2)
'Q' unsigned long long int 8 (2)
'f' float float 4  
'd' double float 8  
        参考来源: https://docs.python.org/3.6/library/array.html

3、示例

        a、共享内存 —— value
from multiprocessing import Value,Process 
import time 
import random 

#向共享内存存钱
def deposite(money):
    for i in range(100):
        time.sleep(0.03)
        money.value += random.randint(1,200)
#从共享内存取钱
def withdraw(money):
    for i in range(100):
        time.sleep(0.02)
        money.value -= random.randint(1,150)

#创建共享内存对象
money = Value('i',2000)

d = Process(target = deposite,args = (money,))
w = Process(target = withdraw,args = (money,))
d.start()
w.start()
d.join()
w.join()

#查看共享内存数据
print(money.value)
        b、共享内存 —— array
from multiprocessing import Array,Process 
import time 

def fun(shm):
    for i in shm:
        print(i)
    shm[2] = 1000

#开辟共享内存空间,可容纳6个整数
#初始值是[1,2,3,4,5,6]
# shm = Array('i',[1,2,3,4,5,6])
#表示在共享内存中开辟一个包含6个整形的空间
shm = Array('i',6)

p = Process(target = fun,args = (shm,))
p.start()
p.join()
for i in shm:
    print(i)













八、附录:目录

        人工智能(PythonNet)—— 目录汇总


猜你喜欢

转载自blog.csdn.net/qq_27297393/article/details/81042017