Centos OS 上的不同进程的 UUID 保持不变,但在 Windows OS 上工作正常(每个进程流的 UUID)

UUID stayed the same for different processes on Centos OS, but works fine on Windows OS (UUID per Process flow)

我 运行 在 Python 3.9 中有两个源文件。 (文件很大...)

文件一(fileOne.py)

# ...
sessionID = uuid.uuid4().hex
# ...

文件二(fileTwo.py)

# ...
from fileOne import sessionID
# ...

文件二使用模块 multiprocessing 执行。

我的问题:为什么这在本地(Windows OS)按预期工作,但在 CentOS VM 上却不行?

更新 1.0: 说清楚。

对于每个单独的进程,我需要 FileOne 和 FileTwo 的 UUID 相同。这意味着

当您 运行 您的脚本时,它会生成 uuid 的新值,但是当您 运行 它在某些服务中时,您的代码与以下代码相同:

sessionID = 123 # simple constant

因此,要解决此问题,您可以尝试将代码包装到函数中,例如:

def get_uuid():
    return uuid.uuid4().hex

在你的第二个文件中:

from frileOne import get_uuid

get_uuid()    

您的谜语很可能是由多处理在不同操作系统中的工作方式引起的。你没有提到,但你的“运行 本地”肯定是 Windows 或 MacOS,而不是 Linux 或其他 Unix Flavor。

问题是 Linux 上的多处理(以及之前在 MacOS 上的多处理,但在 Python 3.8 上更改了它),在使用多处理时使用了系统 fork 调用:当前流程是“按原样”复制的,其所有定义的变量和 类 - 由于您的 sessionID 是在导入时定义的,因此它在所有子流程中保持不变。

Windows 缺少 fork 调用,并且 multiprocessing 求助于启动一个新的 Python 解释器,该解释器从当前进程重新导入所有模块(这导致另一个更常见的混淆的原因,其中任何不受条目 Python 文件上的 if __name__ == "__main__": 保护的代码被重新执行)。在您的情况下,sessionID 的值已重新生成。

查看文档:https://docs.python.org/3/library/multiprocessing.html#contexts-and-start-methods

因此,如果您希望变量在 运行 多处理时可靠地运行并在所有进程中具有相同的值,您应该将其作为参数传递给其他进程中的目标函数,或者使用适当的结构来跨流程共享价值,如下所述: https://docs.python.org/3/library/multiprocessing.html#sharing-state-between-processes

(您也可以查看最近关于同一主题的问题:

如果您需要为每个不同的进程提供跨文件的唯一 ID: (从编辑和评论中看得更清楚)

有一个全局(普通)字典,它将作为每个进程的 ID 注册表,并使用一个函数来检索 ID - 该函数可以使用 os.getpid() 作为注册表的键。

文件 1:

import os
import uuid
...
_id_registry = {}

def get_session_id():
    return _id_registry.setdefault(os.getpid(), uuid.uuid4())

文件 2:

from file1 import get_session_id

sessionID = get_session_id()

(如果设置了 none,setdefault dict 方法负责提供新的 ID 值)

注意:以这种方式设置的注册表将最多保留主进程 ID(如果多进程正在使用 fork 模式)和它自己 - 没有兄弟姐妹的数据,因为每个进程都会保留它的自己的注册表副本。如果您需要一个有效的进程间字典(例如,它可以为所有进程保存一个实时注册表),您可能会更好地使用 redis(https://redis.io - 当然 Python 绑定之一有一个透明的 Python-mapping-over-redis,所以你不必担心它的语义)