- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我有一台使用 apache2 和 mod_python 的服务器,它似乎在短时间后重置了全局变量。在此之前,服务器和全局变量的所有功能都完全按照我的预期进行处理。
为了排除某些运行时错误的可能性(尽管我确实进行了调试并且没有看到任何错误),我制作了这个简化的脚本来演示如何重置全局变量。它只是持有一个全局计数器并在每次访问服务器时递增它:
from mod_python import apache
counter = 0
def handler(req):
global counter
counter += 1
req.content_type = 'text/plain'
req.write('counter: '+str(counter))
return apache.OK
我可以不断刷新页面并观察计数器按预期上升。然而,在某些时候计数器会跳回 1。
我试着简单地按住 F5 键来快速刷新页面,看看在我不断访问它时它是否仍然会重置,然后我注意到了一些别的东西。一开始还会有几次降到1,最后会降到其他数。例如,我的刷新次数达到了 200 次左右,而它刚刚下降到 100 次左右,偶尔甚至会跳回 200 次。
似乎正在启动的服务器脚本有多个虚拟外壳,服务器只是在它们之间随机切换或启动新的。我怎样才能避免这种情况?
最佳答案
It seems like there are multiple virtual shells for the server script being started, and the server just randomly switches between them or starts new ones.
没错。
Apache 有很多不同的事情可以最大限度地提高并发性,其中之一就是生成一堆子进程。
使用 mod_python
,每个子进程都有自己独立的 Python 解释器,这意味着它们每个都有自己的任何全局变量副本。
How can I prevent this?
好吧,您可以在 Apache 中禁用 fork 。但这是个坏主意。除非您真的知道自己在做什么,否则这会扼杀您的可扩展性。如果您重新启动服务器(Apache 有时会自行清除内存泄漏,除非您将其配置为不这样做),它仍然无济于事。
Web 服务应该是无状态的——或者更确切地说,如果它们有任何状态,它们应该将其打包并在请求之间持久保存。对于每个用户的状态,您可以将其存储在 cookie 或隐藏的表单字段中,并让他们的浏览器将其传回。但是对于系统范围的状态,那是行不通的;您需要将其保存到外部。
通常的解决方案是数据库。但是对于这么简单的事情,您可以使用任何东西——甚至是一个纯文本文件和一个 flock。这是冗长的,但无需学习 SQL 或其他一些数据库接口(interface)就很容易理解,它会让你思考并发问题(理解它们是至关重要的),所以我将展示:
import contextlib
import fcntl
from mod_python import apache
@contextlib.contextmanager
def flocking(f, flag=fcntl.LOCK_EX):
fcntl.flock(f, flag)
try:
yield f
finally:
fcntl.flock(f, fcntl.LOCK_UN)
def bump_counter():
while True:
try:
with flocking(open('storage.lock', 'r+')) as f:
val = int(f.read())
f.seek(0)
f.write(str(val))
return val
except OSError:
pass
try:
with flocking(open('storage.lock', 'x')) as f:
val = 0
f.write(str(val))
return val
except OSError:
pass
def handler(req):
req.content_type = 'text/plain'
req.write('counter: '+str(bump_counter()))
return apache.OK
大部分代码都是关于错误处理的,主要是处理第一次请求,所以文件还不存在的情况。在这种情况下,我们尝试以 x
模式打开它,只有当文件不存在时才会成功,以防万一两个请求在您启动时正确进入并且他们都认为他们'重新开始。这样,其中一个会失败,然后返回并再次尝试整个循环。
在现实生活中,您需要更好的错误处理,因为“找不到文件”并不是失败的唯一原因,而且您不希望服务器在这种情况发生时永远阻塞。但在现实生活中,您可能会使用一个数据库来为您处理这件事。
关于python - 为什么我的 mod_python 全局变量会重置?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25943645/
尝试使用集成到 QTCreator 的表单编辑器,但即使我将插件放入 QtCreator.app/Contents/MacOS/designer 也不会显示。不过,相同的 dylib 文件确实适用于独
在此代码示例中。 “this.method2();”之后会读到什么?在返回returnedValue之前会跳转到method2()吗? public int method1(int returnedV
我的项目有通过gradle配置的依赖项。我想添加以下依赖项: compile group: 'org.restlet.jse', name: 'org.restlet.ext.apispark', v
我将把我们基于 Windows 的客户管理软件移植到基于 Web 的软件。我发现 polymer 可能是一种选择。 但是,对于我们的使用,我们找不到 polymer 组件具有表格 View 、下拉菜单
我的项目文件夹 Project 中有一个文件夹,比如 ED 文件夹,当我在 Eclipse 中指定在哪里查找我写入的文件时 File file = new File("ED/text.txt"); e
这是奇怪的事情,这个有效: $('#box').css({"backgroundPosition": "0px 250px"}); 但这不起作用,它只是不改变位置: $('#box').animate
这个问题在这里已经有了答案: Why does OR 0 round numbers in Javascript? (3 个答案) 关闭 5 年前。 Mozilla JavaScript Guide
这个问题在这里已经有了答案: Is the function strcmpi in the C standard libary of ISO? (3 个答案) 关闭 8 年前。 我有一个问题,为什么
我目前使用的是共享主机方案,我不确定它使用的是哪个版本的 MySQL,但它似乎不支持 DATETIMEOFFSET 类型。 是否存在支持 DATETIMEOFFSET 的 MySQL 版本?或者有计划
研究 Seam 3,我发现 Seam Solder 允许将 @Named 注释应用于包 - 在这种情况下,该包中的所有 bean 都将自动命名,就好像它们符合条件一样@Named 他们自己。我没有看到
我知道 .append 偶尔会增加数组的容量并形成数组的新副本,但 .removeLast 会逆转这种情况并减少容量通过复制到一个新的更小的数组来改变数组? 最佳答案 否(或者至少如果是,则它是一个错
很难说出这里要问什么。这个问题模棱两可、含糊不清、不完整、过于宽泛或夸夸其谈,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开,visit the help center . 关闭 1
noexcept 函数说明符是否旨在 boost 性能,因为生成的对象中可能没有记录异常的代码,因此应尽可能将其添加到函数声明和定义中?我首先想到了可调用对象的包装器,其中 noexcept 可能会产
我正在使用 Angularjs 1.3.7,刚刚发现 Promise.all 在成功响应后不会更新 angularjs View ,而 $q.all 会。由于 Promises 包含在 native
我最近发现了这段JavaScript代码: Math.random() * 0x1000000 10.12345 10.12345 >> 0 10 > 10.12345 >>> 0 10 我使用
我正在编写一个玩具(物理)矢量库,并且遇到了 GHC 坚持认为函数应该具有 Integer 的问题。是他们的类型。我希望向量乘以向量以及标量(仅使用 * ),虽然这可以通过仅使用 Vector 来实现
PHP 的 mail() 函数发送邮件正常,但 Swiftmailer 的 Swift_MailTransport 不起作用! 这有效: mail('user@example.com', 'test
我尝试通过 php 脚本转储我的数据,但没有命令行。所以我用 this script 创建了我的 .sql 文件然后我尝试使用我的脚本: $link = mysql_connect($host, $u
使用 python 2.6.4 中的 sqlite3 标准库,以下查询在 sqlite3 命令行上运行良好: select segmentid, node_t, start, number,title
我最近发现了这段JavaScript代码: Math.random() * 0x1000000 10.12345 10.12345 >> 0 10 > 10.12345 >>> 0 10 我使用
我是一名优秀的程序员,十分优秀!