简体   繁体   English

具有多处理功能的对象池在Python中返回相同的对象

[英]Object pool with multiprocessing returns the same object in Python

I have object pool to manage some resource. 我有对象池来管理一些资源。 I expected to use reused resources to be created with different Processes. 我希望使用可通过不同流程创建的重用资源。 But I see that all resources have the same ID and are created as new object. 但是我看到所有资源都具有相同的ID,并被创建为新对象。


My result is: 我的结果是:

  • Creating new resource = 1 创建新资源= 1
  • Creating new resource = 2 创建新资源= 2
  • Creating new resource = 3 创建新资源= 3
  • Creating new resource = 1 创建新资源= 1
  • Creating new resource = 2 创建新资源= 2
  • Creating new resource = 3 创建新资源= 3
  • Creating new resource = 1 创建新资源= 1
  • Creating new resource = 2 创建新资源= 2
  • Creating new resource = 3 创建新资源= 3

I expected to see something like this: 我希望看到这样的东西:

  • Creating new resource = 1 创建新资源= 1
  • Creating new resource = 2 创建新资源= 2
  • Creating new resource = 3 创建新资源= 3
  • Using existing resource = 1 使用现有资源= 1
  • Using existing resource = 2 使用现有资源= 2
  • Using existing resource = 3 使用现有资源= 3
  • Using existing resource = 1 使用现有资源= 1
  • Using existing resource = 2 使用现有资源= 2
  • Using existing resource = 3 使用现有资源= 3

OR: 要么:

  • Creating new resource = 1 创建新资源= 1
  • Creating new resource = 2 创建新资源= 2
  • Creating new resource = 3 创建新资源= 3
  • Creating new resource = 4 创建新资源= 4
  • Creating new resource = 5 创建新资源= 5
  • Creating new resource = 6 创建新资源= 6
  • Creating new resource = 7 创建新资源= 7
  • Creating new resource = 8 创建新资源= 8
  • Creating new resource = 9 创建新资源= 9

import multiprocessing

class Resource(object): def __init__(self, ID): self.id = ID class ObjectPool: __id = 0 __instance = None __resources = list() def __init__(self): if ObjectPool.__instance != None: raise NotImplemented("This is a singleton class.") @staticmethod def getInstance(): if ObjectPool.__instance == None: ObjectPool.__instance = ObjectPool() return ObjectPool.__instance def getResource(self): if len(self.__resources) > 0: resourse = self.__resources.pop(0) print "Using existing resource = ", resourse.id return resourse else: ObjectPool.__id += 1 print "Creating new resource = ", ObjectPool.__id return Resource(ID=ObjectPool.__id) def returnResource(self, resource): self.__resources.append(resource) POOL = ObjectPool.getInstance() def func(): resource = POOL.getResource() resource2 = POOL.getResource() resource3 = POOL.getResource() POOL.returnResource(resource) POOL.returnResource(resource2) POOL.returnResource(resource3) if __name__ == "__main__": for n in range(3): process = multiprocessing.Process(target=func) process.start()

您从未更改过ObjectPool.id的值,因此它始终为零。

The code is not performing as expected because each new process created with multiprocessing.Process is creating a new local POOL instance. 代码未按预期执行,因为使用multiprocessing.Process创建的每个新进程都在创建一个新的本地POOL实例。

That should become obvious if you add the process id to the printed messages, like: 如果将进程ID添加到打印的消息中,那应该变得显而易见,例如:

import os

[...]

print "[%04d] Using existing resource = %s" % (os.getpid(), resourse.id)

Without more context on what a resource is, it's difficult to suggest a solution to your problem. 如果没有关于资源是什么的更多背景信息,就很难为您的问题提出解决方案。 One option would be to create a shared Queue in the main process and let your processes to get the shared resources from them, and maybe, add them there once they are free'd. 一种选择是在流程中创建一个共享Queue ,然后让您的流程从共享流程中获取共享资源,也许可以在空闲时将其添加到其中。

Or possibly use a Semaphore if the number of shared resources if fixed. 如果共享资源的数量固定,则可以使用Semaphore

Check the documentation for more options. 查看文档以获取更多选项。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM