def generate_times():
now = datetime.datetime.now()
next_time = datetime.datetime(now.year, now.month, now.day, now.hour, now.minute)
while True:
yield next_time
next_time += datetime.timedelta(minute=1)
def past_times():
for time in generate_times():
while time > datetime.datetime.now() - datetime.timedelta(minute=1):
time.sleep(1.0)
yield time
1)这是(几乎)线程安全的。dict上的单个操作是线程安全的,并且您的读取线程不应该从仍在写入的密钥中读取数据。例外情况是以下竞态条件,它依赖于在分钟边界附近发生的上下文切换。在
线程在2014年9月13日的第1:59点收到一条消息
线程2:检查时间(现在是2014-05-20 13:38:00.000),因此它从2014_05_20_13_37读取
线程1:将其消息追加到2014_05_20_13_37队列的末尾
2)不,这不是一个好的设计,不仅仅是因为在螺纹安全条件下存在边缘情况。如果你需要保证每分钟都有东西,睡觉是一种很容易出错的方法。首先,睡眠操作不会在给定的时间内完全睡眠。它至少睡了那么长时间。第二,即使是准确的,你的其他操作仍然需要一些时间,这意味着你的睡眠呼叫之间会有毫秒的漂移。这两个因素可能会导致你每6000-60000分钟就少一分钟。在
忽略第一部分中您的种族条件,我将执行以下操作:
第一个函数创建一个生成器,它生成所有的实时时间,第二个函数确保时间已经过去。在
处理第一部分中的争用情况最简单的方法可能是mag线程2滞后2分钟而不是仅仅落后一分钟(或者1分7秒或16分钟,随便你怎么想)。这仍然不是防故障的:如果您的内核长时间处于停滞状态,那么这些竞争条件仍然可能发生,但这是一个完美的风暴场景。在
如果你想100%正确,那么线程1需要保持一个时间戳来跟踪它最近一次写日志的时间,但是你需要检查非阻塞IO,以确保你的最后一个日志不会停止,如果没有什么是线程1被卡住等待记录的东西。一、 我自己,只会使用2分钟内的过去的时间函数,而不是1,除非这是关键任务日志的生命依赖。在
我不喜欢睡眠(60)和时间增量(分钟=1)的耦合。我认为您可能会得到时间不准确,随着时间的推移,可能会导致跳过写入输出中的基准。在
相反,我会利用两个事实:
记住这一点,您就知道完成这一分钟的输入的时间,然后就可以用最后60分钟的数据写入文件。你的第二个线程只会休眠,直到条件为真。然后它会唤醒,将条件更改到下一分钟,处理数据,然后返回到等待条件再次触发的状态。实际上,您只编写了一个简单的队列,在分钟边界上同步。在
考虑为此使用一个外部存储-redis将是我的选择,因为它的运行独立于应用程序,所以可以避免任何线程问题。另外,redis在这类事情上速度很快。在
相关问题 更多 >
编程相关推荐