【问题标题】:Why do new objects in multiprocessing have the same id?为什么多处理中的新对象具有相同的 id?
【发布时间】:2016-02-13 05:41:37
【问题描述】:

我尝试在使用多处理模块时在进程中创建新对象。但是,有些事情让我感到困惑。

当我使用多处理模块时,新对象的id是一样的

for i in range(4):
    p = multiprocessing.Process(target=worker)
    p.start()

def worker():
    # stanford named entity tagger
    st = StanfordNERTagger(model_path,stanford_ner_path)
    print id(st)    # all the processes print the same id

但是当我使用线程时,它们是不同的:

for i in range(4):
    p = threading.Thread(target=worker)
    p.start()

def worker():
    # stanford named entity tagger
    st = StanfordNERTagger(model_path,stanford_ner_path)
    print id(st)    # threads print differnt ids

我想知道为什么它们不同。

【问题讨论】:

  • afaik 它是从程序空间开始的偏移量......线程共享程序空间......多处理为每个进程创建新的程序空间
  • 这是有道理的。谢谢。

标签: python multiprocessing


【解决方案1】:

id 在 CPython 中返回给定对象的指针。由于线程共享地址空间,一个对象的两个不同实例将被分配在两个不同的位置,返回两个不同的 id(也称为虚拟地址指针)。

对于拥有自己地址空间的独立进程来说,情况并非如此。碰巧他们得到了相同的地址指针。

请记住,地址指针是虚拟的,因此它们表示进程地址空间本身的偏移量。这就是为什么它们是相同的。

通常最好不要依赖 id() 来区分对象,因为新对象可能会得到旧对象的 id,随着时间的推移很难跟踪它们。它通常会导致棘手的错误。

【讨论】:

  • 谢谢!现在我明白了。
  • 如果正确,请将答案标记为正确,以便其他人阅读
  • 在python中有没有更好的获取对象/变量的地址(物理)?我需要知道在 python 多处理中内存分配到底是如何发生的。我知道 linux fork() 是写时复制。但如果我能知道如何跟踪对象地址,这将有助于我更好地理解多处理。
  • 恐怕没有简单的方法可以在 Python 中获取对象的实际物理地址。您可以在 ctypes 中包装一些低 Linux 级别的函数,例如 virt_to_phys,但我相信它不会那么那么简单。此外,通过读取物理地址来理解高级语言的内存分配可能是您可以遵循的最令人沮丧的路径。您需要处理操作系统内存分页和缓存以及其他几个极端情况。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-05-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多