C:多生产者,多消费者边界队列

问题描述

我尝试(最好尝试)通过以下接口实现循环缓冲区:

.poll()

应该可以同时(甚至并行)读取/写入多个元素。例如:

ring_buffer *ring_buffer_create(int capacity,int element_size);
void ring_buffer_destroy(ring_buffer *buffer)

const void *ring_buffer_read_acquire(ring_buffer *buffer,ring_buffer_loc *loc);
void ring_buffer_read_finish(ring_buffer *buffer,ring_buffer_loc loc);

void *ring_buffer_write_acquire(ring_buffer *buffer,ring_buffer_loc *loc);
void ring_buffer_write_finish(ring_buffer *buffer,ring_buffer_loc loc);

所有“获取功能都应被阻止,直到可以进行操作为止。

到目前为止,太好了。我以为这很简单,所以我从基于互斥的干净实现开始。但是很快我发现对于我的用例来说,这太慢了(每秒10万次读写),所以我切换到了自旋锁等。

我的实现变得非常混乱,在某个时候(现在),我开始思考为什么不存在具有所需接口的类似“简单”的东西?也许,重新实现这样的东西不是一个好主意。

也许有人知道具有这种接口的实现,并且如果无法执行该操作会阻塞?我在互联网上找了很长时间,但是找不到适合我的问题的匹配项。也许我想要的界面只是“不好”或“错误”?

尽管如此,我还是添加了当前代码。它基本上为每个“单元”(=值)分配一个状态,该状态可以为NONE(未设置;该单元基本上为空),WRITING(某人已获取要写入数据的单元),READING(某人已获取要读取的单元)和SET (该单元格具有一个可以读取的值)。每个单元格都有一个自旋锁,用于更新单元格状态。

它的工作原理如下: 当某人获取读取并且当前单元格具有状态“ SET”时,则可以读取该值(新状态为READING),并且读取索引增加。在所有其他情况下,条件变量用于等待直到元素可用。元素读取完成后,单元状态将更改为NONE,并且如果有任何写入器正在等待,则将发送条件变量信号。

如果获取单元写入,则同样如此。唯一的区别是,该单元需要使用状态“ NONE”,如果可能,则发出可能的读取器信号。

由于某些原因,代码有时会锁定,因此我必须在条件变量中添加“脏”超时。如果可以解决这个问题,我将非常高兴,因为“超时”基本上使代码轮询(相对难看),并且同时完成了许多上下文切换。也许有人看到了这个错误? “新”代码还有一个缺点,就是有时它确实很慢,这对我的应用程序来说是致命的。我附加了“旧”和“新”代码(已标记更改的行)。

谢谢您的帮助:)!

ring_buffer *buffer = ring_buffer_create(10,sizeof(int));

/* Write a single element */
ring_buffer_loc loc0;
int *i0 = ring_buffer_write_acquire(buffer,&loc);
*i0 = 42; // this Could be a big data structure and way more expensive
ring_buffer_write_finish(buffer,loc0);

/* Write "concurrently" */
ring_buffer_loc loc1,loc2;
int *i1 = ring_buffer_write_acquire(buffer,&loc);
int *i2 = ring_buffer_write_acquire(buffer,&loc);
*i1 = 1729;
*i2 = 314;
ring_buffer_write_finish(buffer,loc1);
ring_buffer_write_finish(buffer,loc2);

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...