# pysharedmap **Repository Path**: lyramilk/pysharedmap ## Basic Information - **Project Name**: pysharedmap - **Description**: 用共享内存实现的python字典,仅支持map一种数据结构。 - **Primary Language**: C++ - **License**: Apache-2.0 - **Default Branch**: main - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2025-01-12 - **Last Updated**: 2025-01-13 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 安装 补充上传到pypi了,传的sdist,所以也支持python2。 ``` pip3 install sharedmap ``` # 示例 ``` import sharedmap def t1(): wmap = sharedmap.rbtree(); wmap.set("aaa","323"); wmap.set("zb","1233"); wmap.set("tes","32z"); wmap.set("红","32是"); print(wmap.get("tes")); wmap.share("test:3325",force=True); print("测试写入"); t1(); def t2(): rmap = sharedmap.sharedmap("test:3325"); print(rmap.get("红")); print("测试读取"); t2(); ``` # 工具类 ## rbtree 这个类用c++代码模拟了一个简单的字符串字典。该字典可以通过```share```方法向共享内存写入一个```sharedmap```。 ### ```set``` | 参数 | 类型 | 说明 | | - | - | - | | key | str | | | val | str | | | 返回值 | bool | 成功True | 该方法失败的时候会抛出异常。 ### ```get``` | 参数 | 类型 | 说明 | | - | - | - | | key | str | | | 返回值 | str | | ### ```share``` 把字典当前状态制作成一个快照(基于索引的内存池和avl树)保存到共享内存中,这个快照可以通过```sharedmap```读取。 | 参数 | 类型 | 说明 | | - | - | - | | name | str | 共享字典的名字,sharedmap在初始化的时候会用到 | | force | bool | 如果该名字的共享字典已经存在,是否删掉旧的重建。 | | 返回值 | bool | 成功True | 该方法失败的时候会抛出异常。 ### ```dump``` 把字典当前状态制作成一个快照返回成```bytes```这个二进制数组其实就是```sharedmap```的内存结构。(目前没提供读取的办法,所以这个方法其实没什么意义) | 参数 | 类型 | 说明 | | - | - | - | | name | str | 共享字典的名字,sharedmap在初始化的时候会用到 | | 返回值 | bytes | 成功True | ### ```remove``` 这是一个静态方法,用户删除由```share```方法构造的共享内存```sharedmap```,删除操作不要求和写入操作在同一个进程中。删除后,已经获取的```sharedmap```依然有效,无法通过该名字获得```sharedmap```对象。删除后可以通过```share```方法建立新的```sharedmap```。更多细节和清理内存的时机参考共享内存的原理。 | 参数 | 类型 | 说明 | | - | - | - | | name | str | 共享字典的名字,sharedmap在初始化的时候会用到 | | 返回值 | bool | 成功True | ## sharedmap ### ```__init__``` 通过给定的名字获得一个共享内存字典,该字典数据必须是由上面的```rbtree```对象通过```share```方法写入的。 | 参数 | 类型 | 说明 | | - | - | - | | name | str | | ### ```get``` | 参数 | 类型 | 说明 | | - | - | - | | key | str | | | 返回值 | str | | # 实现原理 avl树是完美平衡树,在内存中可以用连续的内存块表示,同时avl树的读取操作并不需要在其内存结构中写入任何辅助的信息。avl树的插入操作成本非常高(用给定的有序定长数组构造avl树很快),但读取速度非常快。红黑树插入方便。 共享内存中的数据修改需要在多个不同的进程中用锁来控制,是比较困难的,所以本文的方案是禁用了共享字典的持续写入能力。用红黑树初始化一个字典,然后制作成avl树快照供后续读取。一个共享内存字典的生命周期内,只允许一次性的写入操作,因此具有极好的无锁并发读取特性。 但缺点也是存在的,想要更新共享字典中的数据,需要用红黑树加载所有数据修改后再全量写入共享内存。而且重新写入后,已经被加载的共享字典变成了那些进程的私有数据脱离了共享内存,占用一块内存不说,还不会更新,只能通过销毁对象重新创建或者重启进程来更新数据。可以说修改成本是非常非常高的。