Python缓存的生存时间

时间:2021-10-18 22:51:30

I have multiple threads running the same process that need to be able to to notify each other that something should not be worked on for the next n seconds its not the end of the world if they do however.

我有多个线程运行相同的进程,需要能够相互通知在接下来的n秒内不应该处理的事情,如果他们这样做的话,它不是世界末日。

My aim is to be able to pass a string and a TTL to the cache and be able to fetch all the strings that are in the cache as a list. The cache can live in memory and the TTL's will be no more than 20 seconds.

我的目标是能够将字符串和TTL传递给缓存,并能够将缓存中的所有字符串作为列表获取。缓存可以存在于内存中,TTL不会超过20秒。

Does anyone have a any suggestions for how this can be accomplished?

有没有人对如何实现这一点有任何建议?

3 个解决方案

#1


13  

You can use the expiringdict module:

您可以使用expiringdict模块:

The core of the library is ExpiringDict class which is an ordered dictionary with auto-expiring values for caching purposes.

该库的核心是ExpiringDict类,它是一个有序字典,具有用于缓存目的的自动过期值。

In the description they do not talk about multithreading, so in order not to mess up, use a Lock.

在描述中他们不讨论多线程,所以为了不搞乱,使用Lock。

#2


3  

The OP is using python 2.7 but if you're using python 3, ExpiringDict mentioned in the accepted answer is currently, well, expired. The last commit to the github repo was June 17, 2017 and there is an open issue that it doesn't work with Python 3.5

OP正在使用python 2.7,但如果您使用的是python 3,则接受的答案中提到的ExpiringDict目前已经过期了。对github仓库的最后一次提交是在2017年6月17日,并且有一个未解决的问题,它不适用于Python 3.5

There is a more recently maintained project cachetools (last commit Jun 14, 2018)

最近维护的项目缓存工具(最后提交2018年6月14日)

pip install cachetools

pip install cachetools

from cachetools import TTLCache

cache = TTLCache(maxsize=10, ttl=360)
cache['apple'] = 'top dog'
...
>>> cache['apple']
'top dog'
... after 360 seconds...
>>> cache['apple']
KeyError exception thrown

ttl is the time to live in seconds.

ttl是在几秒钟内生活的时间。

#3


2  

Something like that ?

那样的东西?

from time import time, sleep
import itertools
from threading import Thread, RLock
import signal


class CacheEntry():
  def __init__(self, string, ttl=20):
    self.string = string
    self.expires_at = time() + ttl
    self._expired = False

  def expired(self):
    if self._expired is False:
      return (self.expires_at < time())
    else:
      return self._expired

class CacheList():
  def __init__(self):
    self.entries = []
    self.lock = RLock()

  def add_entry(self, string, ttl=20):
    with self.lock:
        self.entries.append(CacheEntry(string, ttl))

  def read_entries(self):
    with self.lock:
        self.entries = list(itertools.dropwhile(lambda x:x.expired(), self.entries))
        return self.entries

def read_entries(name, slp, cachelist):
  while True:
    print "{}: {}".format(name, ",".join(map(lambda x:x.string, cachelist.read_entries())))
    sleep(slp)

def add_entries(name, ttl, cachelist):
  s = 'A'
  while True:
    cachelist.add_entry(s, ttl)
    print("Added ({}): {}".format(name, s))
    sleep(1)
    s += 'A'



if __name__ == "__main__":
  signal.signal(signal.SIGINT, signal.SIG_DFL)

  cl = CacheList()
  print_threads = []
  print_threads.append(Thread(None, read_entries, args=('t1', 1, cl)))
  # print_threads.append(Thread(None, read_entries, args=('t2', 2, cl)))
  # print_threads.append(Thread(None, read_entries, args=('t3', 3, cl)))

  adder_thread = Thread(None, add_entries, args=('a1', 2, cl))
  adder_thread.start()

  for t in print_threads:
    t.start()

  for t in print_threads:
    t.join()

  adder_thread.join()

#1


13  

You can use the expiringdict module:

您可以使用expiringdict模块:

The core of the library is ExpiringDict class which is an ordered dictionary with auto-expiring values for caching purposes.

该库的核心是ExpiringDict类,它是一个有序字典,具有用于缓存目的的自动过期值。

In the description they do not talk about multithreading, so in order not to mess up, use a Lock.

在描述中他们不讨论多线程,所以为了不搞乱,使用Lock。

#2


3  

The OP is using python 2.7 but if you're using python 3, ExpiringDict mentioned in the accepted answer is currently, well, expired. The last commit to the github repo was June 17, 2017 and there is an open issue that it doesn't work with Python 3.5

OP正在使用python 2.7,但如果您使用的是python 3,则接受的答案中提到的ExpiringDict目前已经过期了。对github仓库的最后一次提交是在2017年6月17日,并且有一个未解决的问题,它不适用于Python 3.5

There is a more recently maintained project cachetools (last commit Jun 14, 2018)

最近维护的项目缓存工具(最后提交2018年6月14日)

pip install cachetools

pip install cachetools

from cachetools import TTLCache

cache = TTLCache(maxsize=10, ttl=360)
cache['apple'] = 'top dog'
...
>>> cache['apple']
'top dog'
... after 360 seconds...
>>> cache['apple']
KeyError exception thrown

ttl is the time to live in seconds.

ttl是在几秒钟内生活的时间。

#3


2  

Something like that ?

那样的东西?

from time import time, sleep
import itertools
from threading import Thread, RLock
import signal


class CacheEntry():
  def __init__(self, string, ttl=20):
    self.string = string
    self.expires_at = time() + ttl
    self._expired = False

  def expired(self):
    if self._expired is False:
      return (self.expires_at < time())
    else:
      return self._expired

class CacheList():
  def __init__(self):
    self.entries = []
    self.lock = RLock()

  def add_entry(self, string, ttl=20):
    with self.lock:
        self.entries.append(CacheEntry(string, ttl))

  def read_entries(self):
    with self.lock:
        self.entries = list(itertools.dropwhile(lambda x:x.expired(), self.entries))
        return self.entries

def read_entries(name, slp, cachelist):
  while True:
    print "{}: {}".format(name, ",".join(map(lambda x:x.string, cachelist.read_entries())))
    sleep(slp)

def add_entries(name, ttl, cachelist):
  s = 'A'
  while True:
    cachelist.add_entry(s, ttl)
    print("Added ({}): {}".format(name, s))
    sleep(1)
    s += 'A'



if __name__ == "__main__":
  signal.signal(signal.SIGINT, signal.SIG_DFL)

  cl = CacheList()
  print_threads = []
  print_threads.append(Thread(None, read_entries, args=('t1', 1, cl)))
  # print_threads.append(Thread(None, read_entries, args=('t2', 2, cl)))
  # print_threads.append(Thread(None, read_entries, args=('t3', 3, cl)))

  adder_thread = Thread(None, add_entries, args=('a1', 2, cl))
  adder_thread.start()

  for t in print_threads:
    t.start()

  for t in print_threads:
    t.join()

  adder_thread.join()