在python中,是否应该在生成器中使用with语句?要清楚,我不是要求使用装饰器从生成器函数创建上下文管理器.我在询问是否存在使用with语句作为生成器内部的上下文管理器的固有问题,因为它至少在某些情况下会捕获StopIteration和GeneratorExit异常.以下是两个例子.
Beazley的例子(第106页)提出了这个问题的一个很好的例子.我已将其修改为使用with语句,以便在opener方法中的yield之后显式关闭文件.我还添加了两种方法,可以在迭代结果时抛出异常.
import os
import fnmatch
def find_files(topdir, pattern):
for path, dirname, filelist in os.walk(topdir):
for name in filelist:
if fnmatch.fnmatch(name, pattern):
yield os.path.join(path,name)
def opener(filenames):
f = None
for name in filenames:
print "F before open: '%s'" % f
#f = open(name,'r')
with open(name,'r') as f:
print "Fname: %s, F#: %d" % (name, f.fileno())
yield f
print "F after yield: '%s'" % f
def cat(filelist):
for i,f in enumerate(filelist):
if i ==20:
# Cause and …Run Code Online (Sandbox Code Playgroud) 给定一个通过mmap'd文件创建大型linux内核页面缓存的进程,在具有内存限制的docker容器(cgroup)中运行会导致内核slab分配错误:
Jul 18 21:29:01 ip-10-10-17-135 kernel: [186998.252395] SLUB: Unable to allocate memory on node -1 (gfp=0x2080020)
Jul 18 21:29:01 ip-10-10-17-135 kernel: [186998.252402] cache: kmalloc-2048(2412:6c2c4ef2026a77599d279450517cb061545fa963ff9faab731daab2a1f672915), object size: 2048, buffer size: 2048, default order: 3, min order: 0
Jul 18 21:29:01 ip-10-10-17-135 kernel: [186998.252407] node 0: slabs: 135, objs: 1950, free: 64
Jul 18 21:29:01 ip-10-10-17-135 kernel: [186998.252409] node 1: slabs: 130, objs: 1716, free: 0
Run Code Online (Sandbox Code Playgroud)
看着slabtop我可以看到在以内存限制开始的容器中,buffer_head,radix_tree_node和kmalloc *对象的数量受到严格限制。这似乎会对应用程序中的IO吞吐量产生病理影响,并且可以通过观察到iostat。即使页面缓存消耗了在容器外部运行的主机OS上的所有可用内存或没有内存限制的容器,也不会发生这种情况。
这似乎是内核内存记帐中的一个问题,其中不将内核页面高速缓存计入容器内存,而是将其支持的SLAB对象计入容器内存。该行为似乎是异常的,因为在预先分配了一个大的平板对象池时运行,内存受限的容器运行良好,可以自由地重用现有的平板空间。只有在容器中分配的平板才计入容器。内存和内核内存的容器选项的组合似乎无法解决此问题(除非根本不设置内存限制,或者设置的限制太大以至于不能限制平板,但这会限制可寻址空间)。我试图通过cgroup.memory=nokmem引导完全禁用kmem记帐,但没有成功。
系统信息:
在python numexpr中安全地将值分配给您正在操作的同一个数组以避免创建临时数组吗?
从项目主页上的内存使用描述看起来没问题,但没有深入到源代码中,这几乎不是一个可靠的答案.
我尝试了下面哪个工作正常,但我希望得到更熟悉这个包的人的确认:
import numpy as np
import numexpr as ne
a = np.ones(5)
b = a.copy()
ne.evaluate("a+b",out=a)
array([ 2., 2., 2., 2., 2.])
Run Code Online (Sandbox Code Playgroud) python ×2
amazon-ecs ×1
docker ×1
generator ×1
java ×1
linux-kernel ×1
mmap ×1
numexpr ×1
numpy ×1