Python3之无法在进程池中使用队列Queue的解决方案

本文介绍了Python中使用multiprocessing模块进行进程间通信的方法,重点讲解了Manager对象的使用及如何利用队列实现进程间的共享数据交换。同时,还探讨了__getstate__和__setstate__方法在对象序列化过程中的作用。
import multiprocessing
import time


class Test:
    def __init__(self):
        self.pool = multiprocessing.Pool()
        # self.queue = multiprocessing.Queue()
        m = multiprocessing.Manager()
        self.queue = m.Queue()

    def subprocess(self):
        for i in range(10):
            print("Running")
            time.sleep(1)
        print("Subprocess Completed")

    def start(self):
        self.pool.apply_async(func=self.subprocess)
        print("Subprocess has been started")
        self.pool.close()
        self.pool.join()

    def __getstate__(self):
        self_dict = self.__dict__.copy()
        del self_dict['pool']
        return self_dict

    def __setstate__(self, state):
        self.__dict__.update(state)


if __name__ == '__main__':
    test = Test()
    test.start()

主要是这两行代码:

m = multiprocessing.Manager()
self.queue = m.Queue()

A manager object returned by Manager() controls a server process which holds Python objects and allows other processes to manipulate them using proxies.

A manager returned by Manager() will support types list, dict, Namespace, Lock, RLock, Semaphore, BoundedSemaphore, Condition, Event, Barrier, Queue, Value and Array.

共享数据主要通过在内存中共享某个数据类型实现的,共享数据类型比较多:列表,字典,同步锁,递归锁,信号量,时间,还有队列等,这个进程池用的就是共享数据的队列类型数据

话说__getstate__和__setstate__是什么鬼?

这个是Python中有些无法被pickle序列化的对象,调用这两个方法后就可以进行pickle序列化和反序列化处理处理。示例:

class Foo(object):
    def __init__(self, val=2):
        self.val = val

    def __getstate__(self):
        # print("I'm being pickled")
        self.val *= 2
        print(self.__dict__)
        return self.__dict__
        print('=--------->')

    def __setstate__(self, d):
        # print("I'm being unpickled with these values:", d)
        self.__dict__ = d
        # self.val *= 3
        # pass
        print('============>')


import pickle

f = Foo()
f_string = pickle.dumps(f)
f_new = pickle.loads(f_string)
print(f_new.val)

上面的示例可以很好的解释了__getstate__和__setstate__用法,Python 将只 pickle 当它调用该实例的__getstate__() 方法时返回给它的值,在 unpickle 时,Python 将提供经过 pickle 的值作为参数传递给实例的__setstate__() 方法。在 __setstate__() 方法内,可以根据经过 pickle 的名称和位置信息来重建对象,并将该对象分配给这个实例的 属性。
这个博客写的超级赞:
pickle序列化全接触

### 回答1: 在 Python 中,可以使用 `multiprocessing` 库中的 `Queue` 来在进程池中传递信息。 首先,在主进程创建一个 `Queue` 对象,然后将该对象作为参数传递给进程池中的每个进程: ```python from multiprocessing import Queue, Process def worker(queue): # 从队列中获取信息 message = queue.get() # 处理信息 print(message) if __name__ == '__main__': # 创建一个队列 queue = Queue() # 创建进程池,并将队列作为参数传递给每个进程 with Process(target=worker, args=(queue,)) as process: # 向队列中添加信息 queue.put('Hello, World!') # 等待进程完成 process.join() ``` 在进程池中的每个进程中,可以使用 `Queue.get()` 方法从队列中获取信息,并使用 `Queue.put()` 方法向队列中添加信息。 注意,在使用进程池队列时,应该使用 `multiprocessing` 库中的进程队列,而不是 `threading` 库中的线程和队列。 ### 回答2: 在Python使用进程池时,可以使用队列来传递信息。 首先,需要导入`multiprocessing`模块中的`Pool`和`Queue`。 使用`Pool`创建进程池对象,可以指定进程数。然后,使用`Queue`创建一个队列对象,用于在进程之间传递信息。 在主进程中,将需要传递的信息通过`put`方法放入队列中。 在子进程中,使用`get`方法从队列中取出信息。 下面是一个示例代码: ```python from multiprocessing import Pool, Queue def worker(queue): data = queue.get() # 从队列中取出信息 # 进行子进程的操作 if __name__ == '__main__': pool = Pool(processes=4) # 创建进程池,指定进程数为4 queue = Queue() # 创建队列对象 for i in range(10): queue.put(i) # 向队列中放入信息 pool.apply_async(worker, (queue,)) # 在进程池中异步执行worker函数 pool.close() # 关闭进程池 pool.join() # 等待所有子进程结束 ``` 在上面的示例代码中,创建了一个进程池对象`pool`,队列对象`queue`以及放入队列的信息。 然后,通过`apply_async`方法在进程池中异步执行`worker`函数,并将队列作为参数传递给子进程。 子进程使用`get`方法从队列中取出信息。 最后,关闭进程池并等待所有子进程结束。 这样,就可以在Python使用队列进程池中传递信息了。 ### 回答3: 在Python中,在进程池使用队列进行信息传递的方法如下: 首先,需要导入`multiprocessing`模块中的`Pool`和`Queue`: ```python from multiprocessing import Pool, Queue ``` 然后,创建一个共享队列对象: ```python queue = Queue() ``` 接下来,在进程池的任务函数中,通过将队列作为参数传递给进程池中的函数,在不同的进程之间进行信息传递: ```python def task_function(queue): # 在进程中需要传递的信息 message = "Hello from process {}".format(os.getpid()) # 将信息放入队列queue.put(message) # 创建进程池 pool = Pool() # 向进程池中添加任务 pool.apply_async(task_function, args=(queue,)) # 关闭进程池 pool.close() # 等待所有任务完成 pool.join() ``` 在上述代码中,我们调用了`apply_async`方法向进程池中添加任务,并将队列作为参数传递给任务函数`task_function`。然后,我们关闭进程池,并使用`join`方法等待所有任务的完成。 最后,可以通过在主进程中从队列中获取数据来获得在进程中传递的信息: ```python while not queue.empty(): message = queue.get() print(message) ``` 上述代码中的`queue.empty()`方法用于判断队列是否为空,`queue.get()`方法用于从队列中获取数据。 通过以上步骤,就可以在Python进程池使用队列进行信息传递了。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值