我正在开发一个令人困惑的结果,开发一个工作流程,重复快速流程,需要按照准确的计划运行,每个实例都由一个可以在自己的时间运行的较慢的功能成功。代码是:
from thread import start_new_thread
import datetime
import time
# log text with current timestamp
def log_event(msg=''):
with open('log.txt', "a") as myfile:
timestring = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
myfile.write(timestring + ' - ' + msg + '\n')
def new_thread(asynchronous, stage):
stage -= 1
if stage < 0:
return
if asynchronous:
log_event( 'new process, stage ' + str(stage) )
start_new_thread(new_thread, (False, stage))
log_event( 'start slow process, stage ' + str(stage) )
time.sleep(5) # simulate slow process to run asynchronously
log_event( 'end slow process, stage ' + str(stage) )
else:
log_event( 'continuing process, stage ' + str(stage) )
time.sleep(2)
start_new_thread(new_thread, (True, stage))
new_thread(True, 3)
log_event('end')
..记录以下内容:
2014-03-12 21:11:18 - new process, stage 2
2014-03-12 21:11:18 - continuing process, stage 1
2014-03-12 21:11:18 - start slow process, stage 2
2014-03-12 21:11:20 - new process, stage 0
2014-03-12 21:11:20 - start slow process, stage 0
2014-03-12 21:11:23 - end slow process, stage 2
2014-03-12 21:11:23 - end
2014-03-12 21:11:25 - end slow process, stage 0
我很困惑为什么有几份报告丢失 - 例如第0和第2阶段的new process, stage 1
,continuing process
等等。我也对奇怪的排序感到困惑:例如我希望缓慢的流程能够按顺序开始和结束。我可能错过了一些关于它是如何工作的东西。
非常感谢我出错的地方。
答案 0 :(得分:1)
这种代码是让人们不建议线程的代码 - 你可能会在日志文件的操作上遇到竞争条件,因为你重新打开了它每个线程。 即使你正在睡觉&#34;大间隔,你也开始一些线程,它们的开始之间没有间隔 - (每对&#34;异步&#34;&#34;同步&#34;新线程没有人工等待(呼叫{{1只有几行代码将它们分开)。所以可能发生的事情是日志文件是用同一时间用不同的文件描述符编写的,其中一个写操作就被丢弃了。
为此,您可以为程序全局打开日志文件,并在所有线程中重复使用open-file对象 - 这样就是O.S.可能会处理多次调用以写入文件。但是,另一方面,正如您所看到的,这种问题只会随着系统的发展而扩大:这就是“重大新闻”的原因。在新的Python版本中是名为asyncio的异步框架(AKA Tulip) - 它已经被旧版Pythona后移,包括Python 2.7作为Trollius - 它们为并发编程提供了与线程不同的范例,并且如果你正在进行的项目非常重要,那值得关注。