python中值过期的容器

python中值过期的容器,python,multithreading,timeout,containers,Python,Multithreading,Timeout,Containers,我想要一个线程安全的Python容器,其中的值在一段时间后自动删除。这样的类存在吗?也许您需要一个LRU缓存。这是我一直想尝试的一个: 它似乎是线程安全的。这或多或少是我现在想要的: from datetime import datetime, timedelta from collections import deque class ExpireCounter: """Tracks how many events were added in the preceding time p

我想要一个线程安全的Python容器,其中的值在一段时间后自动删除。这样的类存在吗?

也许您需要一个LRU缓存。这是我一直想尝试的一个:


它似乎是线程安全的。

这或多或少是我现在想要的:

from datetime import datetime, timedelta
from collections import deque

class ExpireCounter:
    """Tracks how many events were added in the preceding time period
    """

    def __init__(self, timeout=timedelta(seconds=1)):
        self.timeout = timeout
        self.events = deque()

    def add(self):
        """Add event time
        """
        self.events.append(datetime.now())

    def __len__(self):
        """Return number of active events
        """
        self.expire()
        return len(self.events)

    def expire(self):
        """Remove any expired events
        """
        now = datetime.now()
        try:
            while self.events[0] + self.timeout < now:
                self.events.popleft()
        except IndexError:
            pass # no more events


if __name__ == '__main__':
    import time
    c = ExpireCounter()
    assert(len(c) == 0)
    c.inc()
    time.sleep(0.75)
    c.inc()
    assert(len(c) == 2)
    time.sleep(0.75)
    assert(len(c) == 1)
从datetime导入datetime,timedelta
从集合导入deque
类过期计数器:
“”“跟踪在上一个时间段中添加了多少个事件
"""
定义初始化(self,timeout=timedelta(seconds=1)):
self.timeout=超时
self.events=deque()
def添加(自我):
“”“添加事件时间”
"""
self.events.append(datetime.now())
定义(自我):
“”“返回活动事件的数目。”
"""
self.expire()
返回len(self.events)
def过期(自我):
“”“删除任何过期事件。”
"""
now=datetime.now()
尝试:
当self.events[0]+self.timeout
以下是ExpireCounter的线程安全版本:

import datetime
import collections
import threading

class ExpireCounter:
    """Tracks how many events were added in the preceding time period
    """

    def __init__(self, timeout=1):
        self.lock=threading.Lock()        
        self.timeout = timeout
        self.events = collections.deque()

    def add(self,item):
        """Add event time
        """
        with self.lock:
            self.events.append(item)
            threading.Timer(self.timeout,self.expire).start()

    def __len__(self):
        """Return number of active events
        """
        with self.lock:
            return len(self.events)

    def expire(self):
        """Remove any expired events
        """
        with self.lock:
            self.events.popleft()

    def __str__(self):
        with self.lock:
            return str(self.events)
可以这样使用:

import time
c = ExpireCounter()
assert(len(c) == 0)
print(c)
# deque([])

c.add(datetime.datetime.now())
time.sleep(0.75)
c.add(datetime.datetime.now())    
assert(len(c) == 2)
print(c)
# deque([datetime.datetime(2010, 11, 19, 8, 50, 0, 91426), datetime.datetime(2010, 11, 19, 8, 50, 0, 842715)])

time.sleep(0.75)
assert(len(c) == 1)
print(c)
# deque([datetime.datetime(2010, 11, 19, 8, 50, 0, 842715)])

可能重复:我在寻找一个线程安全类,每个值都有超时。该示例使用一个列表和一个全局超时。我希望一个值在给定的超时之后过期,而不管我有多少个值以及是否访问它们。在这种情况下,您可以为每个值存储一个过期时间。您想要什么类型的容器语义:列表、集合、dict或其他?不关心容器的类型,只要它对于Shane是线程安全的+1。当容器过期时,不要尝试从容器中移除内容(特别是当您有多个线程时);取而代之的是,为每个项目存储一个过期时间,并在检索项目时检查项目是否过期。谢谢!我喜欢线程超时。我的示例不是线程安全的吗?文档中说,“deque是一种无限队列的替代实现,具有快速原子append()和popleft()操作,不需要锁定。”@Plumo:我不擅长判断线程安全性,但我认为您的ExpireCounter版本可能不是线程安全的。在
add
方法中,调用
datetime.now()
后可能不会立即调用
self.events.append
。想象一下,多个线程几乎同时调用
add
方法。大量调用
datetime.now
,但结果会以混乱的顺序附加到
self.events
。如果
self.events
没有按时间顺序排列,那么
expire
方法中的while循环可能会过早结束。因此,它可能无法
popleft
所有超时的元素。