三十一、管道,进程数据共享,进程池,进程池的返回值,回调函数

一、管道

管道:进程与进程之间能相互通信
通信原理:是基于管道双向通信
from multiprocessing import Pipe, Process
conn1, conn2 = Pipe()
conn1.send("123456")
print(conn2.recv())
from multiprocessing import Pipe, Process
def func(conn):
    while True:
        msg = conn.recv()
        if msg == None:
            break
        print(msg)


if __name__ == '__main__':
    conn1, conn2 = Pipe()
    Process(target=func, args=(conn1,)).start()
    for i in range(10):
        conn2.send("吃了么")
    conn2.send(None)



"""
#第二种:
def func(conn1, conn2):
    conn2.close()
    while True:
        try:
            msg = conn1.recv()
            print(msg)
        except EOFError :
            conn1.close()
            break


if __name__ == '__main__':
    conn1, conn2 = Pipe()
    Process(target=func, args=(conn1,conn2)).start()
    conn1.close()
    for i in range(10):
        conn2.send("吃了么")
    conn2.close()
    # 疑问:主进程关闭通道不会影响子进程接收数据
    #
    # ********应该特别注意管道端点的正确管理问题,如果是生产者或者消费者中都没有使用管道的某个端点,就应该将它关闭
    这也说明为何在生产中关闭了管道的输出端,在消费者中关闭管道的输入端。如果忘记执行这些步骤,程序可能在消费者中
    的recv()操作阻塞。管道是由操作系统进行引用计数的,必须在所有进程中关闭管道后才能生成EOFError异常
    因此,在生产中关闭管道不会有任何效果,除非消费者也关闭了相同的管道端点
    # """
例子
from multiprocessing import Pipe, Process, Lock
import random, time


def producer(con, pro, name, food):
    con.close()
    for i in range(4):
        time.sleep(random.randint(1, 3))
        f = "%s生产%s%s" % (name, food, i)
        print(f)
        pro.send(f)
    pro.close()


def consumer(con, pro, name):
    pro.close()
    while True:
        try:
            # lock.acquire()
            food = con.recv()
            # lock.release()
            print("%s吃了%s" % (name, food))
            time.sleep(random.randint(1, 3))
        except EOFError:
            print("%s吃完啦" % name)
            con.close()
            break


if __name__ == '__main__':
    con, pro = Pipe()
    # lock = Lock()
    p = Process(target=producer, args=(con, pro, "猪狗", "泔水"))
    p.start()
    c = Process(target=consumer, args=(con, pro, "逗比"))
    c1 = Process(target=consumer, args=(con, pro, "坦克" ))
    c.start()
    c1.start()
    con.close()
    pro.close()

# Pipe 管道数据不安全(可能发生多进程抢一个数据)枷锁来控制抢资源对象   管道属于最底层的东西
# 队列是 管道+锁 所以比较安全,一般用队列
"""
    应该特别注意管道端点的正确管理问题,如果是生产者或者消费者中都没有使用管道的某个端点,就应该将它关闭
    这也说明为何在生产中关闭了管道的输出端,在消费者中关闭管道的输入端。如果忘记执行这些步骤,程序可能在消费者中
    的recv()操作阻塞。管道是由操作系统进行引用计数的,必须在所有进程中关闭管道后才能生成EOFError异常
    因此,在生产中关闭管道不会有任何效果,除非消费者也关闭了相同的管道端点
"""
管道消费者模型

二、进程之间的数据共享

模块:Manager

from multiprocessing import Manager, Process, Lock
def main(dic, lock): lock.acquire() dic["count"] -= 1 lock.release() print(dic) if __name__ == '__main__': lock = Lock() # 牺牲效率变成串行(同步),但是安全 m = Manager() # 可以把数据共用多个进程共享,但是会发生多个子进程抢同一个资源,造成数据混乱,使用必须加锁 dic = m.dict({"count": 100}) p_lis = [] for i in range(50): p = Process(target=main, args=(dic, lock)) p_lis.append(p) # 把对象添加到列表 p.start() for i in p_lis: i.join() # 把每个对象添加join,所有子进程结束,主进程才运行 print("主进程:", dic)

三、进程池

 

转载于:https://www.cnblogs.com/wukai66/p/11358991.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Python中的multiprocessing模块提供了多种处理多进程的方式,其中之一就是使用Pool类来创建进程。 使用Pool类的步骤如下: 1. 首先导入multiprocessing模块中的Pool类: ```python from multiprocessing import Pool ``` 2. 创建Pool对象,指定进程中的进程数: ```python pool = Pool(processes=4) # 进程中有4个进程 ``` 3. 使用Pool对象的map方法调用需要多进程处理的函数: ```python results = pool.map(my_function, my_list) ``` 其中,my_function是需要处理的函数,my_list是需要处理的数据列表。map方法会将my_list中的每一个元素依次传递给my_function函数进行处理,并将处理结果保存在results列表中。 4. 最后记得关闭进程: ```python pool.close() pool.join() ``` 这样就完成了使用Pool类进行多进程处理的操作。注意,在使用Pool类时,需要注意内存占用问题,尽量避免出现内存泄漏等问题。 ### 回答2: Python中的multiprocessing模块提供了一种使用进程来并行执行任务的方法。其中,Pool类是multiprocessing模块中的一个重要组件,用于创建并管理进程。 使用Pool可以很方便地实现多进程并行执行任务,具体步骤如下: 1. 首先,导入multiprocessing模块中的Pool类:`from multiprocessing import Pool` 2. 创建一个Pool实例,指定进程数量,可以使用默认的进程数量(与CPU核心数相同)或者自己指定。例如,创建一个由4个进程组成的进程:`pool = Pool(4)` 3. 使用进程的map()方法来提交任务。map()方法可以接受一个函数和一个可迭代对象作为参数,然后将可迭代对象中的每个元素依次作为参数传递给函数,并发地执行这些任务。示例:`result = pool.map(func, iterable)` 4. 进程会根据系统资源自动创建和管理子进程,将任务分配给这些子进程进行并发执行。执行完成后,会返回一个结果列表,其中每个元素是对应任务的返回值。 5. 随着任务的完成,进程会自动回收并终止子进程,释放系统资源。需要注意的是,在使用完进程后,需要调用close()和join()方法来等待子进程结束并清理资源。示例:`pool.close()`和`pool.join()` Python的multiprocessing模块中的Pool类提供了便捷的多进程管理功能,可以大大提高程序的执行效率。适用于任务间相互独立且计算密集型的应用场景。但当任务之间存在依赖关系或需要共享数据时,需要进一步考虑进程间通信和同步的问题。 ### 回答3: Python中的多进程模块`multiprocessing`中,`Pool`类是一个用于管理进程的工具。它可以帮助我们并行执行多个任务,提高程序的运行效率。 `Pool`类的主要方法包括以下几个: 1. `__init__(self, processes=None, initializer=None, initargs=(), maxtasksperchild=None)`:初始化进程,其中`processes`参数指定进程中的进程数量,默认为CPU的核心数;`initializer`和`initargs`参数可以设置在每个子进程运行之前执行的初始化函数和它的参数;`maxtasksperchild`参数指定每个子进程完成多少个任务后再关闭并重新创建一个新的子进程。 2. `apply(func, args=(), kwds={})`:用于在进程中同步地调用一个函数,并返回函数的执行结果,`args`和`kwds`是函数的参数。 3. `apply_async(func, args=(), kwds={}, callback=None)`:用于在进程中异步地调用一个函数,返回一个`ApplyResult`对象,通过该对象的`get()`方法可以获取函数的执行结果。 4. `map(func, iterable, chunksize=None)`:将函数应用于可迭代对象中的每个元素,并返回执行结果的列表。如果指定了`chunksize`参数,则将可迭代对象分块处理。 5. `map_async(func, iterable, chunksize=None, callback=None)`:与`map()`方法类似,但是是异步地调用函数,返回一个`MapResult`对象。 6. `close()`:停止向进程中添加新的任务。 7. `join()`:等待所有的子进程执行完毕。 通过使用`Pool`类,我们可以轻松地实现多个任务的并行执行,从而加快程序的运行速度。在使用时,需要注意合理设置进程数和合理利用`apply()`、`apply_async()`、`map()`等方法,根据任务的特点选择合适的调用方式,以达到最佳的性能和效果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值