python - Centos 操作系统上不同进程的 UUID 保持不变,但在 Windows 操作系统上工作正常(每个进程流的 UUID)
问题描述
我有两个在 Python 3.9 中运行的源文件。(文件很大……)
文件一(fileOne.py)
# ...
sessionID = uuid.uuid4().hex
# ...
文件二(fileTwo.py)
# ...
from fileOne import sessionID
# ...
文件二使用模块多处理执行。
- 当我在本地机器上运行并在文件 2 中打印 UUID 时,它始终是唯一的。
- 当我在 Centos OS 上运行脚本时,它以某种方式保持不变
- 如果我重新启动服务,UUID 将更改一次。
我的问题:为什么这可以按预期在本地(Windows 操作系统)工作,但不能在 CentOS 虚拟机上工作?
更新 1.0: 说清楚。
对于每个单独的进程,我需要 FileOne 和 FileTwo 的 UUID 相同。意思是说
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 Flavor。
问题是 Linux 上的多处理(直到前一段时间在 MacOS 上,但在 Python 3.8 上改变了它)fork
在使用多处理时使用了系统调用:当前进程是“按原样”复制的,其中包含所有定义的变量和类 -由于您sessionID
是在导入时定义的,因此它在所有子流程中都保持不变。
Windows 缺少fork
调用,并且多处理求助于启动一个新的 Python 解释器,该解释器从当前进程重新导入所有模块(这会导致另一个更常见的混淆原因,其中任何不受if __name__ == "__main__":
入口 Python 文件上的-执行)。在您的情况下,sessionID
将重新生成 for 的值。
检查文档:https ://docs.python.org/3/library/multiprocessing.html#contexts-and-start-methods
因此,如果您希望变量在运行多处理时可靠地运行并且在所有进程中具有相同的值,您应该将其作为参数传递给其他进程中的目标函数,或者使用旨在跨进程共享值的适当结构如此处所述: https ://docs.python.org/3/library/multiprocessing.html#sharing-state-between-processes
(您还可以查看有关同一主题的这个最近的问题:Why is a string printing 3 times instead of 1 when using time.sleep with multiprocessing imports?)
如果您需要每个不同进程的文件中的唯一 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()
(如果没有设置,setdefault dict 方法负责提供新的 ID 值)
注意:以这种方式设置的注册表将最多保留主进程 ID(如果多处理正在使用fork
模式)及其本身 - 没有兄弟姐妹的数据,因为每个进程都将拥有自己的注册表副本。如果您需要一个有效的进程间字典(例如,它可以为所有进程保存一个实时注册表),您可能会更好地使用 redis(https://redis.io - 当然其中一个 Python 绑定具有透明的Python-mapping-over-redis,所以你不必担心它的语义)
推荐阅读
- java - JPA中成员实体的继承问题
- android - 如何从 Android APP 中的 Firebase 动态链接 (FDL) 读取查询参数
- python - Python,无法导入烧瓶-restplus
- visual-studio - 插入制表符而不是空格
- c# - C# 序列化 JSON 对象无法映射到 POST 的目标字段
- sql - 如何在没有重复数据的情况下对两个具有连接的表求和?
- c# - 这个 C# 字典初始化如何正确?
- angular - Cordova & Ionic 4 未找到“FBSDKCoreKit/FBSDKCoreKit.h”文件
- flutter - setState() 在 statefulWidget 类中无法识别
- javascript - 什么会导出 JavaScript/Node.JS 文件?