对于python程序员,我使用后缀Tree包装器。trees/
我每次都需要相同的后缀树实例,在Django中调用一个视图。因此,我将后缀树实例存储在django-cache中,并在每次需要该实例时检索它。
问题1:当我从缓存中检索它时,它总是改变内存位置。即使python使用引用存储数据。
问题2:在2次检索之后,python将出现一个“分段错误(核转储)”。
为什么后缀树的实例从缓存中更改其内存位置?
问题2:为什么会出现分割错误?
问题3:在django的某个地方,他们是否还有其他方式来存储后缀Tree的持久实例,并具有相同的实例?
$ python manage.py shell
Python 2.7.5 (default, Mar 22 2016, 00:57:36)
[GCC 4.7.2 20121109 (Red Hat 4.7.2-8)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>> import SuffixTree
>>> d=SuffixTree.SubstringDict()
>>> d["3132"]=1
>>> d["3"]
[1]
>>> d["4343"]=2
>>> d["3"]
[1, 2]
>>> from django.core.cache import cache
>>> cache.set("c",d,1000)
>>> d
<SuffixTree.SubstringDict.SubstringDict instance at 0x27bd830>
>>> cache.get("c")
<SuffixTree.SubstringDict.SubstringDict instance at 0x27ca908>
>>> cache.get("c")
<SuffixTree.SubstringDict.SubstringDict instance at 0x27ca9e0>
>>> cache.get("c")
Segmentation fault (core dumped)发布于 2016-04-21 08:32:09
问题的关键是Django没有将缓存存储在进程内存中,因此您放入缓存中的所有对象在存储前都是序列化的,当您返回缓存时,它们就反序列化了。每次检索它们时,都会创建新对象,它是存储对象的副本。
它的实现方式是这样的,因为在生产环境中,您将拥有多个django工作进程(可能在不同的服务器上运行)。所有的工作进程都需要共享相同的缓存。因此,您不能在每个请求上拥有相同的实例,因为您的请求可以由不同的工作人员处理。
这个问题的解决办法将因应用程序的用途而有所不同。
根据您的注释,您可以创建一个模块,该模块将在请求之间缓存实例:
from datetime import timedelta, datetime
MAX_LIVE_TIME = timedelta(seconds=3600)
_tree_instance = None
_tree_timestamp = None
def get_cached_tree():
global _tree_instance, _tree_timestamp
if _tree_instance is not None and _tree_timestamp - datetime.now() < MAX_LIVE_TIME:
return _tree_instance
_tree_instance = 'SuffixTree' # Replace this with SuffixTree creation
_tree_timestamp = now()
return _tree_instance然后在视图中调用get_cached_tree()以获得SuffixTree。您在不同的工作人员上仍然有不同的实例,但是它的工作速度要快得多,并且没有分段故障。
分段错误是您使用的Python解释器中的错误的结果,或者更有可能是您使用的包中的错误。您应该确保使用包的最后一个版本(https://github.com/JDonner/SuffixTree),如果没有帮助,您应该分析堆栈跟踪(核心转储),并向SuffixTree回购提交一个bug。
https://stackoverflow.com/questions/36763305
复制相似问题