本地进程间的通信方式

        进程间是无法随意通信的,但有时候我们也需要多个进程间通信,其实操作系统也为我们提供了几种机制来实现进程间的通信;比如说:队列( queue )、管道( pipe )、进程管理器( manager )、信号量等。下面重点介绍一下队列( queue )、管道( pipe )、进程管理器( manager )。

1.Queue ( 队列 )

我们可以使用multiprocessing模块中的Queue(队列)来完成多进程间的数据传递,我们可以通过queue获取队列对象。

队列先进先出,后进后出,和我们日常生活中的排队一样

1.1 queue的常见方法

put(item, block=True, timeout=None): 往队列里放数据。如果满了的话,blocking = False 直接报 Full异常。如果blocking = True,就是等一会,timeout必须为 0 或正数。None为一直等下去,0为不等,正数n为等待n秒还不能存入,报Full异常。

get(item, block=True, timeout=None): 从队列里取数据。如果为空的话,blocking = False 直接报 empty异常。如果blocking = True,就是等一会,timeout必须为 0 或正数。None为一直等下去,0为不等,正数n为等待n秒还不能读取,报empty异常。

其他的请看下面程序:

import queue

# Queue 先进先出 LifeQueue先进后出 后进先出
# print(dir(queue))
# Queue() 可以填入参数 确定有多少;若不填参数 随便填 填多少算多少 这里设置队列长度为3
q = queue.Queue(3)
# q.put() 将一个值放入队列中
q.put("a")
q.put("b")
q.put("c")


# 确定队列的长度
print(q.qsize())
# 判断是否为空,为空返回True,不为空返回False
print(q.empty())
# 判断队列是否满队,如果满队返回True,如果不满队返回False
print(q.full())
# 从队列获取一个数据,获取的数据是队列里传入的时间最长的那个
print(q.get())
print(q.get())
print(q.get())
print(q.qsize())

输出结果为:

3
False
False
a
b
c
0


1.2 当队列长度小于串如数据数目是会阻断进程,比如说:

q = queue.Queue(3)
q.put("a")
q.put("b")
q.put("c")
q.put("d")
# 确定大小
print(q.qsize())
# 判断是否为空
print(q.empty())
# 判断是否不为空
print(q.full())
print(q.get())
print(q.get())
print(q.get())
print(q.get())
print(q.qsize())

运行时不会发现,不会输出任何结果,而且程序也不报错。

1.3 put里的timeout

q = queue.Queue(3)
q.put("a")
q.put("a")
q.put("a")

print(q.qsize())
# 判断是否为空
print(q.empty())
# 判断是否不为空
print(q.full())
print(q.get())
print(q.get())
print(q.get())
q.put("a", block=True, timeout=3)
print(q.qsize())

运行结果如下:

3
False
True
a
a
a
1

1.4 实现进程间的数据传递

from multiprocessing import Process, Pipe


def sendMsg(p):
    msg = "这个是利用管道传输的数据"
    print("一个独立子进程开始传输数据了,数据是:", msg)
    p.send(msg)
    print("数据发送成功")
    p.close()


def receiveMsg(p):
    print("接受到管道传输的数据:", p.recv())


if __name__ == '__main__':
    print("------------start----------------")
    # pipe = Pipe()
    (parentPipe, sonPipe) = Pipe()
    # print(parentPipe, sonPipe)
    task1 = Process(target=sendMsg, args=[parentPipe])
    task1.start()
    task2 = Process(target=receiveMsg, args=[sonPipe])
    task2.start()
    print("------------end----------------")

运行结果如下:

------------start----------------
------------end----------------
一个独立子进程开始传输数据了,数据是: 这个是利用管道传输的数据
数据发送成功
接受到管道传输的数据: 这个是利用管道传输的数据

2. pipe管道

from multiprocessing import Pipe, Process


def send_msg(p):
    msg = "这个是用管道传输的数据"
    print("一个独立子进程开始数据了,数据是:", msg)
    p.send(msg)# 发送数据
    p.close()# 关闭管道


def receive_msg(p):
    print("接收到管道传输的数据是:", p.recv())# p.recv()接受数据


if __name__ == '__main__':
    print("-----------start-------------")
    (per_pipe, son_pipe) = Pipe()
    # print(Pipe())
    t1 = Process(target=send_msg, args=[per_pipe])
    t1.start()
    t2 = Process(target=receive_msg, args=[son_pipe])
    t2.start()
    print("------------end---------------")

运行结果为:

-----------start-------------
------------end---------------
一个独立子进程开始数据了,数据是: 这个是用管道传输的数据
接收到管道传输的数据是: 这个是用管道传输的数据

3. 设备管理器( Manager )

def save_data(l, d):
    l.append("高要")
    l.append("赵本山")
    l.append("刘亦菲")

    d["name"] = "武松"
    d["age"] = "潘金莲"
    d["nickname"] = "西门庆"
    print(l)
    print(d)


# manger里面的进程是守护进程
if __name__ == '__main__':
    print("----------start------------")
    # manager = Manager()
    # lists = manager.list()
    # dicts = manager.dict()
    with Manager() as manager:
        lists = manager.list()
        dicts = manager.dict()
        ls = []
        # 在以一个循环里进程的创建
        for x in range(5):
            t1 = Process(target=save_data, args=[lists, dicts])
            t1.start()
            ls.append(t1)
        for x in ls:
            x.join()

    print("-----------end-------------")

运行结果是:

----------start------------
['高要', '赵本山', '刘亦菲']
{'name': '武松', 'age': '潘金莲', 'nickname': '西门庆'}
['高要', '赵本山', '刘亦菲', '高要', '赵本山', '刘亦菲']
{'name': '武松', 'age': '潘金莲', 'nickname': '西门庆'}
['高要', '赵本山', '刘亦菲', '高要', '赵本山', '刘亦菲', '高要', '赵本山', '刘亦菲']
{'name': '武松', 'age': '潘金莲', 'nickname': '西门庆'}
['高要', '赵本山', '刘亦菲', '高要', '赵本山', '刘亦菲', '高要', '赵本山', '刘亦菲', '高要', '赵本山', '刘亦菲']
{'name': '武松', 'age': '潘金莲', 'nickname': '西门庆'}
['高要', '赵本山', '刘亦菲', '高要', '赵本山', '刘亦菲', '高要', '赵本山', '刘亦菲', '高要', '赵本山', '刘亦菲', '高要', '赵本山', '刘亦菲']
{'name': '武松', 'age': '潘金莲', 'nickname': '西门庆'}


猜你喜欢

转载自blog.csdn.net/qwerLoL123456/article/details/80990739