【问题标题】:Python program doesn't quit when finishedPython程序完成后不会退出
【发布时间】:2011-01-25 15:27:34
【问题描述】:

我有以下脚本 186.py:

S=[]
study=set([524287])

tmax=10**7
D={}
DF={}
dudcount=0
callcount=0

def matchval(t1,t2):
    if t1==t2:
        global dudcount
        dudcount+=1
    else:
        global callcount
        callcount+=1
        D.setdefault(t1,set([]))
        D.setdefault(t2,set([]))
        D[t1].add(t2)
        if t1 in D[t2]:
            DF.setdefault(t1,set([]))
            DF[t1].add(t2)
            DF.setdefault(t2,set([]))
            DF[t2].add(t1)

for k in xrange(27):
    t1=(100003 - 200003*(2*k+1) + 300007*(2*k+1)**3)%(1000000)
    S.append(t1)
    t2=(100003 - 200003*(2*k+2) + 300007*(2*k+2)**3)%(1000000)
    S.append(t2)
    matchval(t1,t2)

t1=(100003 - 200003*(55) + 300007*(55)**3)%(1000000)
S.append(t1)
t2=(S[31]+S.pop(0))%(1000000)
S.append(t2)
matchval(t1,t2)

for k in xrange(29,tmax+1):
    t1=(S[31]+S.pop(0))%(1000000)
    S.append(t1)

    t2=(S[31]+S.pop(0))%(1000000)
    S.append(t2)
    matchval(t1,t2)

D.setdefault(524287,set([]))
DF.setdefault(524287,set([]))
print D[524287]
print DF[524287]
print dudcount,callcount
print "Done"

最后一行打印“完成”,但发生这种情况时 python 不会退出。我输入以下命令:

$ time python 186.py

并得到结果:

set([810528L, 582178L, 49419L, 214483L, 974071L, 651738L, 199163L, 193791L])
set([])
11 9999989
Done

但我必须 ctrl+C 才能获得时间:

real    34m18.642s
user    2m26.465s
sys     0m11.645s

在程序输出“Done”后,python CPU 使用率非常低......但内存使用量继续增长......一旦达到我系统内存的 80%(它是一个旧系统),我就使用了 ctrl+C .

这里发生了什么?打印完成后程序在做什么?不应该做吗?

谢谢, 丹

【问题讨论】:

    标签: python linux memory-leaks


    【解决方案1】:

    在您发布的内容中没有任何迹象表明与描述的症状相符。也许执行代码中的缩进被填充了,你真的要在整个代码堆上运行另一个循环。请注意,当运行需要 34 分钟时,只有勇敢的人才会费心尝试重现您的问题。你能在更短的时间内重现这个问题吗?

    当你使用 Control-C 时,回溯是怎么说的?

    无论如何,我强烈建议不要在所有地方都使用硬编码常量(?),例如524287 .... 给它一个有意义的名字,并在开始时使用meaningful_name = 524287。或者如果它真的是一个变量,请通过sys.argv. 输入它

    【讨论】:

    • 程序运行不需要 34 分钟。运行大约需要 2 分钟,然后不会退出。在决定杀死它之前,我让它再运行了 32 分钟。当我降低 tmax 的值时,它运行得更快,并且没有同样的问题。
    • 哦。所以它正在交换,你 (a) 没有注意到 (b) 注意到但认为它不值得一提?
    • 它是 (a)。我仍然不完全理解交换如何解释这种奇怪的行为......交换清除应该总是比交换写入快,不是吗?掉期清算怎么能比原来的程序长一个数量级?
    【解决方案2】:

    我在配备 2GB RAM 的 2 GHz 双核笔记本电脑上运行了相同的代码,在 Cygwin 中运行了大约 1 1/2 分钟。程序退出前内存使用量上升了600多MB,出现Done后大约2-4秒出现提示并释放内存。但是,Done 出现后我没有看到任何内存增加。

    我的猜测是它与内存管理有关。在Done 出现后,Python 正在努力释放所有内存,这在 RAM 较少的旧机器上可能需要很长时间。我不确定为什么内存实际上会增加,除非只是延迟告诉您正在使用多少内存。

    【讨论】:

    • 好吧,我只有 480 MB 的 RAM。 1.4 GB 的交换。清理内存所需的时间比实际运行程序要长 10 倍,这似乎仍然很奇怪。我正在交换(你可能没有)这一事实能否解释为什么释放内存过程比程序本身花费的时间更长?
    • 做一些进一步的测试...这个问题只适用于交换发生时。我开始认为这不是代码/python问题,而是硬盘写入速度或其他东西的系统问题......所以可能不再是编程问题。感谢您的帮助。