在 Python 中,我想同时执行代码中的 saveData 函数。但是,在第一次运行 saveData 后,我收到了错误:
Traceback (most recent call last):
File "preProcess.py", line 70, in <module>
run()
File "preProcess.py", line 61, in run
thread.start_new_thread(saveData(slice1, slice2, slice3, dset), ("Thread-" + str(i), 1, ) )
TypeError: first arg must be callable
以下是我的代码:
#!/usr/bin/env python
http://www.jshk.com.cn/mb/reg.asp?kefu=xiaoding;//爬虫IP免费获取;
import sys
import numpy as np
import h5py
import scipy
from PIL import Image
import timeit
import thread
import matplotlib.pyplot as plt
def saveImage(array, filename):
fig=plt.figure(figsize=(4,3))
ax=fig.add_subplot(1,1,1)
plt.axis('off')
p = plt.imshow(array)
p.set_cmap('gray')
extent = ax.get_window_extent().transformed(fig.dpi_scale_trans.inverted())
plt.savefig(filename, bbox_inches=extent)
def saveData(value1, value2, value3, dset):
filename = "tomo1_" + str(value1) + ".png"
data = dset[value1::]
saveImage(data, filename)
filename = "tomo2_" + str(value2) + ".png"
data = dset[:value2:]
saveImage(data, filename)
filename = "tomo3_" + str(value3) + ".png"
data = dset[::value3]
saveImage(data, filename)
def run():
# Reopen the file and dataset using default properties.
f = h5py.File(sys.argv[1])
dset = f[sys.argv[2]]
dim1 = len(dset)
dim2 = len(dset[0])
dim3 = len(dset[0][0])
slice1 = 0
slice2 = 0
slice3 = 0
factor1 = dim1/48
factor2 = dim2/48
factor3 = dim3/48
tic=timeit.default_timer()
for i in range(0,48):
thread.start_new_thread(saveData(slice1, slice2, slice3, dset), ("Thread-" + str(i), 1, ) )
slice1 = slice1 + factor1
slice2 = slice2 + factor2
slice3 = slice3 + factor3
toc=timeit.default_timer()
print "elapsed time: " + str(toc - tic)
if __name__ == "__main__":
run()
我希望同时执行 saveData 函数 48 次。我做错了什么?
解决方案
解决方案 1:
正如 Gryphius 指出的那样:您不能在 start_new_thread 中执行 saveData,而应该将您的函数用作 thread.start_new_thread 的普通参数!原因是,thread.start_new_thread 将为您在 Thread 中执行函数。因此,您不仅要将函数作为参数传递(而不执行),还要传递函数的参数:
thread.start_new_thread(saveData,(slice1,slice2,slice3,dset),("Thread-"+str(i),1,))
正如您所看到的,您的函数参数被传递为元组。附带说明一下:这种不调用函数,而是将其与参数一起传递的习惯用法也出现在事件处理函数中:回调。
也可以考虑使用 Threading 包,而不是线程,它更复杂,可以为您提供更多的自由和功能!
解决方案 2:
仔细阅读 thread.start_new_thread 的 api 文档。它期望第一个参数是可调用的,因此在您的情况下只需使用 saveData,而不是 saveData(slice1, slice2, slice3, dset)。第二个参数是一个包含函数参数的元组。
try:
thread.start_new_thread(saveData,(slice1, slice2, slice3, dset))
except:
print("Error: unable to start thread")
希望这些解决方案能帮助您同时执行 saveData 函数 48 次。