SharedArea —— uWSGI组件间共享内存页
警告
SharedArea是一种非常底层的机制。想要一个更易于使用的替代品,可以看看 Caching 和 Queue 框架。
警告
本页面适用于uWSGI 1.9.21中引进的“新一代”sharedarea,不再支持较老的API。
sharedarea子系统允许你以一种非常快速(安全)的方式,在你的uWSGI组件(worker, spooler, mule等等)之间共享内存页。
与较高层次的 caching framework 相比,sharedarea操作是一种更快的方式 (单一的拷贝,而不是如缓存所需的那样要进行双重拷贝),并且它为特定的需求提供不同的优化。
每一个共享区域 (是哒,你可以拥有多个区域) 都有一个大小 (一般根据页面数指定),因此,如果你在拥有4 KiB页面的系统上需要一个8 KiB的共享区域,那么你会使用 sharedarea=2
。
共享区域子系统是完全线程安全的。
简单的选项 VS 键值
sharedarea子系统公开了 (目前) 一个单一的选项: —sharedarea
.
它接收两种参数:页面数 (简单的方法) 或者一个键值参数 (用于高级调试)。
可以使用以下键值键:
pages
– 设置页面数file
– 从一个将会被mmap
的文件中创建共享区域fd
– 从一个将会被mmap
的文件描述符中创建共享区域size
– 主要和fd
和ptr
键使用,用来指定映射的大小 (也可以作为一个快捷方式使用,以避免对pages
值的计算)ptr
– 直接映射该区域到指定的内存指针。
API
API是非常大的,共享区域将会是编写高度优化的web应用(特别是嵌入系统)实际上的玩物。
大多数已记录的使用在拥有缓慢的CPU或者非常少量的内存的系统上有意义。
sharedarea_read(id, pos[, len])
- 从指定的共享区域的偏移
pos
起读取len
字节。如果未指定len
,那么将会读取到内存尾部 (从pos
开始)。 sharedarea_write(id, pos, string)
- 将指定的
string
(显然,它是语言相关的) 写入到指定的共享区域偏移pos
的位置上。 sharedarea_read8|16|32|64(id, pos)
- 从指定的位置读取有符号整数 (8, 16, 32或者64位)。
sharedarea_write8|16|32|64(id, pos)
- 将一个有符号整数 (8, 16, 32或者64位) 写入到指定的位置。
sharedarea_inc8|16|32|64(id, pos)
- 递增指定位置的有符号整数 (8, 16, 32或者64位)。
sharedarea_dec8|16|32|64(id, pos)
- 递减指定位置的有符号整数 (8, 16, 32或者64位)。
sharedarea_wait(id[, freq, timeout])
- 等待指定共享区域的修改 (见下)。
sharedarea_rlock(id)
- 为读取锁定一个共享区域 (只有在你知道你在做什么的时候使用它,一般来说,共享区域api函数自己实现锁)
sharedarea_wlock(id)
- 为写入锁定一个共享区域 (只有在你知道你在做什么的时候使用它,一般来说,共享区域api函数自己实现锁)
sharedarea_unlock(id)
- 解锁一个共享区域 (只有在你知道你在做什么的时候使用它,一般来说,共享区域api函数自己实现锁)
等待更新
共享区域的最有力特性之一 (与缓存相比) 是“等待更新”。你的worker/thread/async_core可以被挂起,直到修改了一个共享区域。
从技术上讲,一个分辨率为毫秒的计时器会被触发,不断地检测更新 (这个操作是非常快的,因为共享区域对象有一个更新计数器,英寸我们只需要检测那个值就知道有没有改动了)。
可选API
以下函数要求语言特定特性,所以并不是所有的语言插件都能够支持它们的。
sharedarea_readfast(id, pos, object, [, len])
- 从指定的共享区域的偏移量
pos
开始,读取len
字节到指定的对象中中。如果不指定len
,那么将会读取到内存尾部 (从pos
开始)。目前只对Perl实现。 sharedarea_memoryview(id)
- 返回你可以直接操作的python memoryview对象 (只在CPython上有用)
sharedarea_object(id)
- 一些插件公开了一个从内部对象创建共享区域的可选的方式。这个函数返回原始对象 (目前只在CPython中,基于字节数组实现,使用
—py-sharedarea <size>
选项)
Websockets集成API
这个目前只在psgi/perl插件中支持:
websocket_send_from_sharedarea(id, pos)
- 直接从指定的共享区域发送一个websocket消息
websocket_send_binary_from_sharedarea(id, pos)
- 直接从指定的共享区域发送一个websocket二进制消息
高级使用 (从C)
正在进行中。