首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >传递给多处理的Python pint对象与在进程中创建的对象具有不同的注册表。

传递给多处理的Python pint对象与在进程中创建的对象具有不同的注册表。
EN

Stack Overflow用户
提问于 2022-10-13 21:06:47
回答 1查看 26关注 0票数 0

我有一个需要multiprocessing的应用程序,其中pint对象作为参数传递给流程,pint对象也在流程中创建。但是,这些不同的pint对象之间有不同的注册中心。

我希望单元注册表在进程中会因为酸洗/去酸洗而发生变化;但是,我希望传入的对象作为参数将具有与在进程中创建的对象相同的注册表。有什么办法确保这一点吗?这是multiprocessingpint的问题吗?还是我做错什么了?

以下是一份妇女权利宣言:

代码语言:javascript
复制
import os
import multiprocessing
import pint

ureg = pint.UnitRegistry()


def f(a):
    print("pid in f: ", os.getpid())
    print("ureg in f: ", ureg)
    print("a's ureg in f: ", a._REGISTRY)

    b = ureg.Unit('m')
    print("b's ureg in f: ", b._REGISTRY)
    try:
        print("a == b: ", a == b)
    except Exception as e:
        print(e)

    return b


if __name__ == "__main__":
    print("pid: ", os.getpid())
    print("ureg in main: ", ureg)

    a = ureg.Unit('m')
    print("a's ureg in main: ", a._REGISTRY, "\n")

    print("Without multiprocessing...")
    b = f(a)
    print("b's ureg in main: ", b._REGISTRY, "\n")

    print("With multiprocessing...")
    ctx = multiprocessing.get_context("spawn")

    with ctx.Pool(1) as pool:
        p = pool.apply_async(f, (a,))
        b = p.get()
    print("b's ureg in main: ", b._REGISTRY, "\n")

产出:

代码语言:javascript
复制
pid:  40977
ureg in main:  <pint.registry.UnitRegistry object at 0x7fd1d475ced0>
a's ureg in main:  <pint.registry.UnitRegistry object at 0x7fd1d475ced0> 

Without multiprocessing...
pid in f:  40977
ureg in f:  <pint.registry.UnitRegistry object at 0x7fd1d475ced0>
a's ureg in f:  <pint.registry.UnitRegistry object at 0x7fd1d475ced0>
b's ureg in f:  <pint.registry.UnitRegistry object at 0x7fd1d475ced0>
a == b:  True
b's ureg in main:  <pint.registry.UnitRegistry object at 0x7fd1d475ced0> 

With multiprocessing...
pid in f:  74218
ureg in f:  <pint.registry.UnitRegistry object at 0x7fb5c612fad0>  # Expected to be different from main ureg
a's ureg in f:  <pint.registry.UnitRegistry object at 0x7fb5cba36290>  # Why is this different from previous line?
b's ureg in f:  <pint.registry.UnitRegistry object at 0x7fb5c612fad0>
Cannot operate with Unit and Unit of different registries.  # This error is expected when registries are different
b's ureg in main:  <pint.registry.UnitRegistry object at 0x7fd1d41ca850>  # Why is this different from main process ureg?
EN

回答 1

Stack Overflow用户

发布于 2022-10-14 01:00:33

实际上,我错过的是set_application_registry。根据序列化文档 (谢谢@juanpa.arrivillaga),

但是,您必须记住,应用程序注册表用于解酸洗,这可能与腌制期间使用的不同。 ..。 如果您的应用程序需要一个带有自定义定义的单一全局注册表,则必须确保它是使用pint.set_application_registry()注册的,然后才能清除任何信息。

因此,multiprocessing进程使用一个不同的注册表来解除酸洗,我可以控制它是什么。修改OP示例:

代码语言:javascript
复制
import os
import multiprocessing
import pint

ureg = pint.UnitRegistry()
pint.set_application_registry(ureg)


def f(a):
    print("pid in f: ", os.getpid())
    print("ureg in f: ", ureg)
    print("a's ureg in f: ", a._REGISTRY)

    b = ureg.Unit('m')
    print("b's ureg in f: ", b._REGISTRY)
    try:
        print("a == b: ", a == b)
    except Exception as e:
        print(e)

    return b


if __name__ == "__main__":
    print("pid: ", os.getpid())
    print("ureg in main: ", ureg)

    a = ureg.Unit('m')
    print("a's ureg in main: ", a._REGISTRY, "\n")

    print("Without multiprocessing...")
    b = f(a)
    print("b's ureg in main: ", b._REGISTRY, "\n")

    print("With multiprocessing...")
    ctx = multiprocessing.get_context("spawn")

    with ctx.Pool(1) as pool:
        p = pool.apply_async(f, (a,))
        b = p.get()
    print("b's ureg in main: ", b._REGISTRY, "\n")

产生预期产出:

代码语言:javascript
复制
pid:  37081
ureg in main:  <pint.registry.UnitRegistry object at 0x1069cf040>
a's ureg in main:  <pint.registry.UnitRegistry object at 0x1069cf040> 

Without multiprocessing...
pid in f:  37081
ureg in f:  <pint.registry.UnitRegistry object at 0x1069cf040>
a's ureg in f:  <pint.registry.UnitRegistry object at 0x1069cf040>
b's ureg in f:  <pint.registry.UnitRegistry object at 0x1069cf040>
a == b:  True
b's ureg in main:  <pint.registry.UnitRegistry object at 0x1069cf040> 

With multiprocessing...
pid in f:  37083
ureg in f:  <pint.registry.UnitRegistry object at 0x10b9df670>  # Expected to be different from main ureg
a's ureg in f:  <pint.registry.UnitRegistry object at 0x10b9df670>  # This is now the same as the previous line
b's ureg in f:  <pint.registry.UnitRegistry object at 0x10b9df670>  # And so is this
a == b:  True  # Yeah! No error
b's ureg in main:  <pint.registry.UnitRegistry object at 0x1069cf040>  # And this is now the same as the main ureg!

我注意到,经过这一更正,a == b在多处理情况下返回pint = 0.18 (但没有错误)的False,但似乎对pint >= 0.19是固定的。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/74061808

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档