UUID在Centos操作系统的不同进程中保持相同,但在Windows操作系统上工作良好(每个进程流的UUID).<



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

文件1 (fileOne.py)

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

文件二(fileTwo.py)

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

文件2使用模块multiprocessing执行。

  • 当我在本地机器上运行并打印文件2中的UUID时,它总是唯一的。
  • 当我在Centos操作系统上运行脚本时,它仍然是相同的
  • 如果我重新启动服务,UUID将改变一次。

我的问题:为什么这工作在本地(Windows操作系统)的预期,而不是在CentOS虚拟机?

更新1.0:让它更清晰。

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

  • processOne = UUID in file one and in file two will be 1q2w3e
  • processTwo = UUID in file one and in file two will be r4t5y6 (a different one)

您的困惑很可能是由不同操作系统中的多处理方式引起的。你没有提到,但你的"本地运行"。当然是Windows或MacOS,而不是Linux或其他Unix版本。

问题是,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

(你也可以检查最近关于同一主题的问题:为什么字符串在使用time时打印3次而不是1次?)

如果您需要在每个不同进程的文件中使用唯一的ID:(从编辑和评论中可以更清楚地看出)

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

文件1:

import os
import uuid
...
_id_registry = {}
def get_session_id():
return _id_registry.setdefault(os.getpid(), uuid.uuid4())

file2:

from file1 import get_session_id
sessionID = get_session_id()

(如果没有设置,setdefault dict方法负责提供一个新的ID值)

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

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

sessionID = 123 # simple constant

所以要解决这个问题,你可以尝试将代码包装到函数中,例如:

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

在你的第二个文件:

from frileOne import get_uuid
get_uuid()    

最新更新