- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我对 Python 子解释器初始化(来自 Python/C API)和 Python id()
函数的内部工作有疑问。更准确地说,是关于在 WSGI Python 容器中处理全局模块对象(例如与 nginx 一起使用的 uWSGI 和 Apache 上的 mod_wsgi)。
以下代码在上述两种环境中都按预期工作(隔离),但我无法向自己解释为什么id()
函数总是返回相同的值 每个变量,无论执行它的进程/子解释器如何。
from __future__ import print_function
import os, sys
def log(*msg):
print(">>>", *msg, file=sys.stderr)
class A:
def __init__(self, x):
self.x = x
def __str__(self):
return self.x
def set(self, x):
self.x = x
a = A("one")
log("class instantiated.")
def application(environ, start_response):
output = "pid = %d\n" % os.getpid()
output += "id(A) = %d\n" % id(A)
output += "id(a) = %d\n" % id(a)
output += "str(a) = %s\n\n" % a
a.set("two")
status = "200 OK"
response_headers = [
('Content-type', 'text/plain'), ('Content-Length', str(len(output)))
]
start_response(status, response_headers)
return [output]
我已经在 uWSGI 中用一个主进程和 2 个工作进程测试了这段代码;在 mod_wsgi 中,使用具有两个进程和每个进程一个线程的守护进程模式。典型的输出是:
pid = 15278
id(A) = 139748093678128
id(a) = 139748093962360
str(a) = one
第一次加载时,然后:
pid = 15282
id(A) = 139748093678128
id(a) = 139748093962360
str(a) = one
第二个,然后
pid = 15278 | pid = 15282
id(A) = 139748093678128
id(a) = 139748093962360
str(a) = two
彼此之间。正如您所看到的,类和类实例的 id()(内存位置)在两个进程(上面的第一个/第二个加载)中保持相同,而在同时类实例存在于单独的上下文中(否则第二个请求将显示“两个”而不是“一个”)!
我怀疑 Python 文档可能暗示了答案:
id(object)
:Return the “identity” of an object. This is an integer (or long integer) which is guaranteed to be unique and constant for this object during its lifetime. Two objects with non-overlapping lifetimes may have the same
id()
value.
但如果这确实是原因,那么我对下一个声明 id()
值是对象地址的语句感到困扰!
虽然我很欣赏这个事实,但这很可能只是一个 Python/C API“聪明”功能,可以解决(或者更确切地说修复) problem of caching object references (pointers) in 3rd party extension modules ,我仍然觉得这种行为不符合……嗯,常识。有人可以解释一下吗?
我还注意到 mod_wsgi 在每个进程中导入模块(即两次),而 uWSGI 对于两个进程仅导入模块一次。由于 uWSGI 主进程执行导入,我想它会为子进程播种该上下文的副本。两个工作人员随后独立工作(深度复制?),同时看似使用相同的对象地址。 (此外,工作人员在重新加载时会重新初始化为原始上下文。)
对于这么长的帖子,我深表歉意,但我想提供足够的细节。谢谢!
最佳答案
您要问的问题并不完全清楚;如果问题更具体,我会给出更简洁的答案。
首先,对象的 id 实际上是(至少在 CPython 中)它在内存中的地址。这是完全正常的:同一进程中的两个对象不能共享地址,并且对象的地址在 CPython 中永远不会改变,因此地址可以很好地用作 id。我不知道这怎么违背常识。
接下来,请注意后端进程可能以两种截然不同的方式产生:
但是,这两种情况的最终结果是相同的:独立的 fork 进程。
那么,为什么你们最终会得到相同的 ID?这取决于使用上述哪种方法。
但是,无论如何,一旦 fork 发生,它们就是单独的对象,在不同的上下文中。不同进程中具有相同 ID 的对象没有任何意义。
关于mod-wsgi - 全局Python对象的唯一性在子解释器中无效?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4146630/
我的应用程序中有一个 settings.php 页面,它使用 $GLOBALS 来存储网络应用程序中使用的配置。 例如,他是我使用的一个示例设置变量: $GLOBALS["new_login_page
我正在尝试编译我们在 OS 类上获得的简单操作系统代码。它在 Ubuntu 下运行良好,但我想在 OS X 上编译它。我得到的错误是: [compiling] arch/i386/arch/start
我知道distcp无法使用通配符。 但是,我将需要在更改的目录上安排distcp。 (即,仅在星期一等“星期五”目录中复制数据),还从指定目录下的所有项目中复制数据。 是否有某种设计模式可用于编写此类
是否可以在config.groovy中全局定义资源格式(json,xml)的优先级,而不是在每个Resource上指定?例如,不要在@Resource Annotation的参数中指定它,例如: @R
是否有一些简单的方法来获取大对象图的所有关联,而不必“左连接获取”所有关联?我不能只告诉 Hibernate 默认获取 eager 关联吗? 最佳答案 即使有可能有一个全局 lazy=false(谷歌
我正在尝试实现一个全局加载对话框...我想调用一些静态函数来显示对话框和一些静态函数来关闭它。与此同时,我正在主线程或子线程中做一些工作...... 我尝试了以下操作,但对话框没有更新...最后一次,
当我偶然发现 this question 时,我正在阅读更改占位符文本。 无论如何,我回去学习了占位符。一个 SO 的回答大致如下: Be careful when designing your pl
例如,如果我有这样的文字: "hello800 more text 1234 and 567" 它应该匹配 1234 和 567,而不是 800(因为它遵循 hello 的 o,这不是一个数字)。 这
我一直在尝试寻找一种无需使用 SMS 验证系统即可验证电话号码(Android 和 iPhone)的方法。原因纯粹是围绕成本。我想要一个免费的解决方案。 我可以安全地假设 Android 操作系统会向
解决此类问题的规范 C++ 设计模式是什么? 我有一些共享多个类的多线程服务器。我需要为大多数类提供各种运行时参数(例如服务器名称、日志记录级别)。 在下面的伪 C++ 代码中,我使用了一个日志记录类
这个问题在这里已经有了答案: Using global variables in a function (25 个答案) 关闭 9 年前。 我是 python 的新手,所以可能有一个简单的答案,但我
这个问题在这里已经有了答案: 关闭 10 年前。 Possible Duplicate: Does C++ call destructors for global and class static
我正在尝试使用 Objective-C 中的 ArrayList 的等价物。我知道我必须使用 NSMutableArray。我想要一个字符串列表 (NSString)。关键是我的列表应该可以从我类(c
今天刚开始学习 Android 开发,我找不到任何关于如何定义 Helper 类或将全局加载的函数集合的信息,我会能够在我创建的任何 Activity 中使用它们。 我的计划是创建(至少目前)2 个几
为什么这段代码有效: var = 0 def func(num): print num var = 1 if num != 0: func(num-1) fun
$GLOBALS["items"] = array('one', 'two', 'three', 'four', 'five' ,'six', 'seven'); $alter = &$GLOBALS
我想知道如何实现一个可以在任何地方使用您自己的设置的全局记录器: 我目前有一个自定义记录器类: class customLogger(logging.Logger): ... 该类位于一个单独的
我需要使用 React 测试库和 Jest 在我的测试中模拟不同的窗口大小。 目前我必须在每个测试文件中包含这个beforeAll: import matchMediaPolyfill from 'm
每次我遇到单例模式或任何静态类(即(几乎)只有静态成员的类)的实现时,我想知道这是否实际上不是一种黑客行为,因此只是为了设计而严重滥用类和实例的原则单个对象,而不是设计类和创建单个实例。对我来说,看起
这个问题在这里已经有了答案: Help understanding global flag in perl (2 个回答) 7年前关闭。 my $test = "There was once an\n
我是一名优秀的程序员,十分优秀!