Python和Cython的无锁环形缓冲区。

ringbuf的Python项目详细描述


林布夫

为Python和Cython提供了一个无锁、单生产者、单用户的环形缓冲区。在

build_status

安装

苹果操作系统:brew install boost

Ubuntu:apt-get install libboost-all-dev

Windows:安装最新版本的^{},然后设置BOOST_ROOT环境变量指向其文件夹。在

然后:

pip install ringbuf

动机

在Python中使用实时DSP时,我们可能会封装一些外部C/C++库(例如PortAudio),它实时运行一些用户提供的回调函数。回调函数不应该分配/释放内存,不应该包含任何关键部分(互斥锁)等等,以防止优先级反转。如果回调包含Python对象,那么我们可能会分配和释放GIL,至少,获取和释放GIL。因此,如果我们期望实时性能,回调就不能与Python对象交互。因此,有必要在C/C++回调和Python之间以非锁定方式缓冲数据。在

^{}输入ringbuf,Cython wrappers。我们的Python代码可以读取和写入^ {< CD6> }对象,并且我们的C++代码可以读取和写入该缓冲区的基础^ {< CD7}},不需要吉尔。在

使用

任何支持buffer protocol的Python对象都可以存储在ringbuf.RingBuffer中。这包括但不限于:bytesbytearrayarray.array,和{}。在

纽比

^{pr2}$

字节

fromringbufimportRingBufferbuffer=RingBuffer(format='B',capacity=11)buffer.push(b'hello world')popped=buffer.pop(11)assertbytes(popped)==b'hello world'

与C/C++ +EH3>接口

在我的模块.pxd公司名称:

# distutils: language = c++cdefvoidcallback(void*q)

在我的模块.pyx公司名称:

# distutils: language = c++fromarrayimportarrayfromringbuf.boostcimportspsc_queue,void_ptr_to_spsc_queue_char_ptrfromringbuf.ringbufcimportRingBufferfromsome_c_librarycimportsome_c_functioncdefvoidcallback(void*q):cdef:# Cast the void* back to an spsc_queue.# The underlying queue always holds chars.spsc_queue[char]*queue=void_ptr_to_spsc_queue_char_ptr(q)double[5]to_push=[1.0,2.0,3.0,4.0,5.0]# Since the queue holds chars, you'll have to cast and adjust size accordingly.queue.push(<char*>to_push,sizeof(double)*5)defdo_stuff():cdef:RingBufferbuffer=RingBuffer(format='d',capacity=100)void*queue=buffer.queue_void_ptr()# Pass our callback and a void pointer to the buffer's queue to some third party library.# Presumably, the C library schedules the callback and passes it the queue's void pointer.some_c_function(callback,queue)sleep(1)assertarray.array('d',buffer.pop(5))==array.array('d',range(1,6))

处理溢出和下溢

RingBuffer.push()溢出时,它返回无法推送的数据(如果全部被推送,则返回无):

fromringbufimportRingBufferbuffer=RingBuffer(format='B',capacity=10)overflowed=buffer.push(b'spam eggs ham')assertoverflowed==b'ham'

RingBuffer.pop()下溢时,它返回可能弹出的任何数据:

fromringbufimportRingBufferbuffer=RingBuffer(format='B',capacity=13)buffer.push(b'spam eggs ham')popped=buffer.pop(buffer.capacity*100)assertbytes(popped)==b'spam eggs ham'

有关其他用法,请参阅tests。在

支持的平台

Travis CI测试采用以下配置:

  • Ubuntu 18.04仿生海狸:
    • CPython3.6版
    • CPython3.7版
    • CPython3.8版
    • PyPy7.3.0(3.6.9)
  • 苹果操作系统:
    • CPython3.6版
    • CPython3.7版
    • CPython3.8版
    • PyPy7.3.0(3.6.9)
<任何一个带有C++ 11编译器的平台都可能运行。已添加Windows支持,但考虑 实验性的。在Windows上为Travis CI测试ringbuf的请求将非常受欢迎。在

贡献

欢迎拉取请求,请将遇到的任何问题归档。在

变更日志

v2.5.0 2020年4月17日

  • 增加了对Windows的实验支持。在

v2.4.0 2020-03-23

  • 添加了RingBuffer.reset()方法来清除缓冲区。在

v2.3.0 2020年3月22日

  • 添加了concatenate函数,用于连接多个支持缓冲区协议的任意Python对象。在

欢迎加入QQ群-->: 979659372 Python中文网_新手群

推荐PyPI第三方库


热门话题
java重写父类中的特定行   java Apache Commons CLI订购帮助选项?   java如何将数据添加到网格视图   java如何在Apache Camel批处理后移动文件?   java如何为日期范围的between子句编写hql查询?   雅加达ee开始Java编程,我应该从哪里开始?   排序Java8+流:检查我的objectinstances的两个字段的列表顺序是否正确   java如何将json转换为Map<String,Object>确保整数为整数   java不能在Spring数据JPA批处理过程中创建TransactionException   java损坏的PDF文件从FTP下载到使用Apache Common Net的设备   java无法使用Spring批处理和Wso2为XML架构命名空间找到Spring NamespaceHandler   java Android ImageView未显示在SherlockFragment中   Maven在构建时出错=无法识别Java路径   java如何使用批处理文件调用关闭处理程序?   java admob广告横幅重叠我的游戏屏幕安卓