如果导入某些模块,Python脚本(带有ctypes)运行缓慢或崩溃

时间:2015-02-17 08:23:45

标签: python memory crash ctypes python-import

更新3 :在您开始阅读更多内容之前,请注意我能够“解决”我遇到的问题!原来,DLL本身存在内存错误。非常奇怪的是,只有在我用Python导入某些模块时才出现内存错误(在c方面)(我仍然不知道这个)。如果您仍然对某些原因感兴趣,请继续阅读...我还提供了用于创建DLL的c程序的链接。 c文件中还有一个注释标识(我相信)导致内存错误的行。

我有以下Python脚本调用DLL进行光线跟踪。代码是有用的,当我运行代码时,我得到以下输出(注释import matplotlib.pyplot as plt行)

输出(不导入matplotlib):

λ python import_problem.py
Time before tracing:  5.92239880841 micro seconds
Ray tracing took 392.607661807  milli seconds

在上述情况下,我能够执行100%的代码(在我尝试的多次运行中)。

但是,如果我只是取消注释行import matplotlib.pyplot as plt,那么,要么执行时间增加很多,要么 Python只是崩溃了“python.exe已停止工作... “。

(我知道我在代码中没有使用这个特定的模块......但它只是为了演示问题。我也尝试导入我编写的另一个模块并看到同样的问题)

另请注意,跟踪较少数量或较大数量的光线不会影响此问题。

到目前为止,我没有任何关于为什么会出现此问题的线索。任何建议都会非常有用。

非常感谢。

我在Windows 7上使用Python 2.7.3(64位)。

更新1: 我还测试了几个其他模块的导入,这里是结果 - 导入Numpy,Scipy,Mayavi根本没有引起任何问题。但是,当我尝试导入过去创建的一些模块(并且没有问题时使用)时,崩溃再次出现。

更新2: 您可以找到用于创建DLL {c-3}}的c源文件。

这是Python脚本:

# file: import_problem.py
import os as os
import time as time
from ctypes import  WinDLL, c_int, c_double, Structure, POINTER
#import matplotlib.pyplot as plt


class DdeArrayData(Structure):
    _fields_ = [(  'x', c_double), ('y', c_double), ('z', c_double),
                (  'l', c_double), ('m', c_double), ('n', c_double),
                ('opd', c_double), ('intensity', c_double),
                ('Exr', c_double), ('Exi', c_double),
                ('Eyr', c_double), ('Eyi', c_double),
                ('Ezr', c_double), ('Ezi', c_double),
                ('wave', c_int),   ('error', c_int),
                ('vigcode', c_int), ('want_opd', c_int)]

def my_function( ):
    num_rays = 441
    rd = (DdeArrayData * (num_rays + 1))()
    # Setup a basic ray data array for test
    rd[0].opd, rd[0].wave = 0.0, 0
    rd[0].error = c_int(num_rays)
    rd[0].want_opd = -1
    k = 0
    for i in xrange(-10, 11, 1):
        for j in xrange(-10, 11, 1):
            k += 1
            rd[k].z, rd[k].l =i/20.0, j/20.0
            rd[k].intensity, rd[k].wave = 1.0, 1

    start_time = time.clock()
    ret = arrayTrace(rd)    # Call the C function
    end_time = time.clock()
    print "Time before tracing: ", (start_time)*10e6, "micro seconds"
    print "Ray tracing took", (end_time - start_time)*10e3, " milli seconds"

if __name__ == '__main__':
    array_trace_lib = WinDLL("C:\\tmp\\ArrayTrace.dll")
    arrayTrace = array_trace_lib.arrayTrace
    arrayTrace.restype = c_int
    arrayTrace.argtypes = [POINTER(DdeArrayData)]
    my_function()

0 个答案:

没有答案