我对下面发布的示例有疑问......
在我的机器上calcIt()
功能大约需要5秒钟才能完成。
从MyClass的callCalcIt()方法内部调用相同的calcIt()
函数。
使用while
循环MyClass是"观看"用calcIt()
函数完成。
问题:calcIt()方法中的while
循环仅打印'...running'
一次。老实说,我期待至少看到一个无限循环' '...running'
每秒打印数千次的行为类型。观察while
循环只执行a print '...running'
行一次的事实让我相信while
循环非常松散地观察{&1;} calcIt()
的进展情况。如果是这样,应该使用其他(除了while
循环)方法来确保你得到你想要的东西:来自calcIt()函数的即时反馈?
def calcIt():
a=True
while a:
for i in range(25000000):
pass
a=False
return True
class MyClass(object):
def __init__(self):
super(MyClass, self).__init__()
def callCalcIt(self):
b=True
while b:
result=calcIt()
print '...running'
if result: b=False
print 0
calcIt()
print 1
c=MyClass()
c.callCalcIt()
print 2
发布修订后的代码,其中包含Ebarr建议的解决方案实施:
import threading
updateMe=[]
def calcIt():
a=True
while a:
for y in range(3):
for i in range(15000000):
pass
updateMe.append(1)
a=False
return True
class MyClass(object):
def __init__(self):
super(MyClass, self).__init__()
def callCalcIt(self):
thread = threading.Thread(target=calcIt)
thread.start()
print '\n...thread started'
while thread.is_alive():
if len(updateMe)==1: print '...stage 1'
if len(updateMe)==2: print '...stage 2'
if len(updateMe)==3: print '...stage 3'
def printUpdate(self):
print 'updateMe=', len(updateMe)
c=MyClass()
c.callCalcIt()
答案 0 :(得分:2)
我不确定你期望发生什么,但解释很简单。您正在运行单线程代码。这意味着以上所有内容都将以串行方式执行,因此代码中的两个while循环之间不会出现并发现象。
您似乎要问的是如何对代码进行处理,以便您可以检查正在运行的函数的进度。如果是这种情况,您可以将calcIt
变为线程。
import threading
class CalcIt(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
def run(self):
for i in range(25000000):
pass
然后,您可以将callCalcIt
更改为:
def callCalcIt(self):
thread = CalcIt()
thread.start()
while thread.is_alive():
print '...running'
或者,您可以更简单:
import threading
def calcIt():
for i in range(25000000):
pass
def callCalcIt():
thread = threading.Thread(target=calcIt)
thread.start()
while thread.is_alive():
print '...running'
callCalcIt()
答案 1 :(得分:1)
我可以提出两种方法,但都需要对calcIt
函数进行一些修改。
方法1,回调:
def calc_it(callback):
r = 25000000
for x in xrange(r+1):
if not (x % 1000):
callback(x, r) # report every 1000 ticks
class Monitor(object):
def print_status(self, x, r):
print "Done {0} out of {1}".format(x, r)
def call(self):
calc_it(self.print_status)
方法2,生成器:
def calc_it():
r = 25000000
for x in xrange(r+1):
if not (x % 1000): # report every 1000 ticks
yield x, r
class Monitor(object):
def call(self):
for x, r in calc_it():
print "Done {0} out of {1}".format(x, r)
(附注:在任何情况下Monitor
都不必是一个类,这只是为了与原始代码保持一致。)
答案 2 :(得分:1)
不确定您要完成的是什么,但您可以使用my newly written generator state machine thingie。像这样:
from generatorstate import State
def calcIt():
while True:
for i in range(25000000):
pass
yield
tick = State(calcIt)
print 0
tick()
print 1
tick()
print 2
我已经添加了几个例子,如果你认为它可能适合,可以偷看一下。