# encoding:utf-8

from collections import OrderedDict
from collections import MutableMapping
from threading import RLock

_Null = object()

def iterkeys(d, **kw):
return d.iterkeys(**kw)

def itervalues(d, **kw):
return d.itervalues(**kw)

class RecentlyUsedContainer(MutableMapping):
"""
Provides a thread-safe dict-like container which maintains up to
``maxsize`` keys while throwing away the least-recently-used keys beyond
``maxsize``.

:param maxsize:
Maximum number of recent elements to retain.

:param dispose_func:
Every time an item is evicted from the container,
``dispose_func(value)`` is called. Callback which will get called
"""

ContainerCls = OrderedDict

def __init__(self, maxsize=10, dispose_func=None):
self._maxsize = maxsize
self.dispose_func = dispose_func

self._container = self.ContainerCls()
self.lock = RLock()

def __getitem__(self, key):
# Re-insert the item, moving it to the end of the eviction line.
with self.lock:
item = self._container.pop(key)
self._container[key] = item
return item

def __setitem__(self, key, value):
evicted_value = _Null
with self.lock:
# Possibly evict the existing value of 'key'
evicted_value = self._container.get(key, _Null)
self._container[key] = value

# If we didn't evict an existing value, we might have to evict the
# least recently used item from the beginning of the container.
if len(self._container) > self._maxsize:
_key, evicted_value = self._container.popitem(last=False)

if self.dispose_func and evicted_value is not _Null:
self.dispose_func(evicted_value)

def __delitem__(self, key):
with self.lock:
value = self._container.pop(key)

if self.dispose_func:
self.dispose_func(value)

def __len__(self):
with self.lock:
return len(self._container)

def __iter__(self):
raise NotImplementedError('Iteration over this class is unlikely to be threadsafe.')

def clear(self):
with self.lock:
# Copy pointers to all values, then wipe the mapping
values = list(itervalues(self._container))
print values
self._container.clear()

if self.dispose_func:
for value in values:
self.dispose_func(value)

def keys(self):
with self.lock:
return list(iterkeys(self._container))

if __name__ == '__main__':
d = RecentlyUsedContainer()
print(dir(d))
d['key1'] = 'value1'
print d._maxsize
# d['key2'] = 'value2'
# d['key3'] = 'value3'
# d['key4'] = 'value4'
# print d.keys()
# del d['key4']
# d.clear()
# print d.keys()

实现线程安全先进先出的dict的更多相关文章

  1. 07-SV线程以及线程间的通信

    1.几种语句块的区别 (1)fork……join:块内语句以并发方式执行 (2)begin……end:块内语句以顺序方式执行 (3)fork……join_none:其块内语句执行时,父线程继续执行 ( ...

  2. 08_线程间通信 ITC

    1.线程间的通信方式 1.共享全局变量 2.线程队列(queue) 3.信号量(Semaphore) 2.共享全局变量进行通信 from threading import Thread import ...

  3. Python中的collections模块

    Python中内置了4种数据类型,包括:list,tuple,set,dict,这些数据类型都有其各自的特点,但是这些特点(比如dict无序)在一定程度上对数据类型的使用产生了约束,在某些使用场景下效 ...

  4. 廖雪峰Python电子书总结

    函数 1.注意:函数的默认参数必须指向不可变对象 未修改前: def add_end(L=[]): L.append('END') return L 存在的问题:如果连续调用多次,会出现多个 'END ...

  5. python基础--常用的模块(collections、time、datetime、random、os、sys、json、pickle)

    collection模块: namedtuple:它是一个函数,是用来创建一个自定义的tuple对象的,并且规定了tuple元素的个数,并可以用属性而不是索引来引用tuple的某个元素.所以我们就可以 ...

  6. step 4 GCD 队列演练

    串行队列 特点 以先进先出的方式,顺序调度队列中的任务执行 无论队列中所指定的执行任务函数是同步还是异步,都会等待前一个任务执行完成后,再调度后面的任务 队列创建 dispatch_queue_t q ...

  7. 在创建窗口句柄之前,不能在控件上调用 Invoke 或 BeginInvoke

    今天关闭一个窗体,报出这样的一个错误"在创建窗口句柄之前,不能在控件上调用 Invoke 或 BeginInvoke.",这个不用多想,肯定是那个地方没有释放掉.既然碰到这个问题, ...

  8. 刀哥多线程之主队列gcd-06-main_queue

    主队列 特点 专门用来在主线程上调度任务的队列 不会开启线程 以先进先出的方式,在主线程空闲时才会调度队列中的任务在主线程执行 如果当前主线程正在有任务执行,那么无论主队列中当前被添加了什么任务,都不 ...

  9. iOS中你必须了解的多线程

    多线程概念详解 什么是进程? 简单的说进程就是我们电脑上运行的一个个应用程序,每一个程序就是一个进程,并且每个进程之间是独立的,每个进程运行在其专用受保护的内存空间内(window系统可以通过任务管理 ...

随机推荐

  1. GIL:全局解释器锁 VS 用户程序锁

    既然有了GIL锁,CPython还要多线程干什么? ''' GIL:全局解释器锁的来历 四核:同一时刻真正有四个任务在运行,多核的意义在于此 单核:看上去是并发的,因为进行了上下文切换,单核永远是串行 ...

  2. 在 Xshell 中 使用 hbase shell 进入后 无法删除

    在 Xshell 中 使用 hbase shell 进入后 无法删除 问题: 在hbase shell下,误输入的指令不能使用backspace和delete删除,使用过的人都知道,这是有多坑,有多苦 ...

  3. 转://看懂Oracle中的执行计划

    一.什么是Oracle执行计划? 执行计划是一条查询语句在Oracle中的执行过程或访问路径的描述 二.怎样查看Oracle执行计划? 2.1 explain plan for命令查看执行计划 在sq ...

  4. 20 python 初学(logging模块)

    学习网站:https://www.cnblogs.com/yuanchenqi/articles/5732581.html logging 模块: # _author: lily # _date: 2 ...

  5. Oracle优化器

    本文参照:https://www.cnblogs.com/Dreamer-1/p/6076440.html 读优化器之前建议先读: https://www.cnblogs.com/zhougongji ...

  6. Golang 入门系列(十一)Go语言实现webapi

    之前,已经讲过很多Golang的东西,比如基础语法,mysql的使用,redis的使用等等,感兴趣的可以看看以前的文章,https://www.cnblogs.com/zhangweizhong/ca ...

  7. Leetcode 226. Invert Binary Tree(easy)

    Invert a binary tree. 4 / \ 2 7 / \ / \ 1 3 6 9 to 4 / \ 7 2 / \ / \ 9 6 3 1 Trivia:This problem was ...

  8. HashMap 与 Hashtable 的区别

    Hashtable t 小写 二者用法一致   都实现Map接口 1.HashMap 的键值可以为null,而Hashtable不允许("null" 不是 null 前者是字符串 ...

  9. ubuntu 18.04安装pytorch、cuda、cudnn等

    版权声明:本文为博主原创文章,欢迎转载,并请注明出处.联系方式:460356155@qq.com ubuntu 16.04用了1年多了,18.04版已经发布也半年了,与时俱进,重装Linux系统,这里 ...

  10. Go语言嵌入类型

    一.什么是嵌入类型 先看如下代码: type user struct { name string email string } type admin struct { user // Embedded ...