以周期间隔记录无限数据

2024-04-16 12:10:06 发布

您现在位置:Python中文网/ 问答频道 /正文

我有无限多的条目通过一个web界面输入。我希望以每分钟为单位,将过去一小时内收到的元素转储到一个名为(datetime.now().strftime('%Y_%m_%d_%H_%M'))的文件中。
以下是我目前为止的设计:

线程1

继续接收输入并添加到结构的data_dict中:
{datetime.now().strftime('%Y_%m_%d_%H_%M'): []}

线程2

{cd4}写了一分钟的内容

问题

  1. 以这种方式使用dict是线程安全的吗?在
  2. 这个设计好吗?:)

Tags: 文件web元素datadatetime界面单位条目
3条回答

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分钟就少一分钟。在

忽略第一部分中您的种族条件,我将执行以下操作:

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

第一个函数创建一个生成器,它生成所有的实时时间,第二个函数确保时间已经过去。在

处理第一部分中的争用情况最简单的方法可能是mag线程2滞后2分钟而不是仅仅落后一分钟(或者1分7秒或16分钟,随便你怎么想)。这仍然不是防故障的:如果您的内核长时间处于停滞状态,那么这些竞争条件仍然可能发生,但这是一个完美的风暴场景。在

如果你想100%正确,那么线程1需要保持一个时间戳来跟踪它最近一次写日志的时间,但是你需要检查非阻塞IO,以确保你的最后一个日志不会停止,如果没有什么是线程1被卡住等待记录的东西。一、 我自己,只会使用2分钟内的过去的时间函数,而不是1,除非这是关键任务日志的生命依赖。在

我不喜欢睡眠(60)和时间增量(分钟=1)的耦合。我认为您可能会得到时间不准确,随着时间的推移,可能会导致跳过写入输出中的基准。在

相反,我会利用两个事实:

  1. 可以等到一分钟后再写文件
  2. 时间只向前移动,所以一旦一分钟过去,你就会知道数据实际上是不可变的

记住这一点,您就知道完成这一分钟的输入的时间,然后就可以用最后60分钟的数据写入文件。你的第二个线程只会休眠,直到条件为真。然后它会唤醒,将条件更改到下一分钟,处理数据,然后返回到等待条件再次触发的状态。实际上,您只编写了一个简单的队列,在分钟边界上同步。在

考虑为此使用一个外部存储-redis将是我的选择,因为它的运行独立于应用程序,所以可以避免任何线程问题。另外,redis在这类事情上速度很快。在

相关问题 更多 >