在C中,我有几个线程产生 long
值,一个线程消耗它们。因此,我需要一个以类似方式实现的固定大小的缓冲区,即Wikipedia implementation,以及以线程安全的方式访问它的方法。
总的来说,以下内容应该成立:
我想使用一个尝试过的实现,最好是从库中。有什么想法吗?
动机&说明:
我正在编写JNI代码,处理在堆对象中删除保留为global references的tags。
当ObjectFree
JVMTI事件发生时,我会得到一个long
标记,表示我需要使用DeleteGlobalRef
释放的全局引用。为此,我需要JNIEnv
引用 - 并且真的代价高昂,所以我想缓冲请求并尽可能多地删除。
可能有很多线程收到ObjectFree
事件,并且会有一个线程(我的)执行引用删除。
答案 0 :(得分:1)
您可以使用单个缓冲区,访问时使用互斥锁。您需要跟踪使用的元素数量。对于“信令”,您可以使用条件变量。生产者线程在将数据放入队列时触发的线程;这将释放使用者线程以处理队列直到空。消费者线程清空队列时触发的另一个消息;这表示任何阻塞的生产者线程填充队列。对于消费者,我建议在释放锁之前锁定队列并尽可能取出(以避免过多的锁),特别是因为出列操作简单快速。
<强>更新强>
一些有用的链接:
* Wikipedia explanation
* POSIX Threads
* MSDN
答案 1 :(得分:1)
两种可能性:
a)malloc()a * Buffer结构,带有一个数组,用于保存一些long和一个索引 - 不需要锁定。让每个生产者线程malloc自己的* Buffer并开始加载它。当生产者线程填充最后一个数组位置时,将* Buffer排队到生产者 - 消费者队列上的消费者线程,并立即将malloc()排队到一个新的* Buffer。消费者获取* Buffers并处理它们然后释放它们(或者将它们排在其他地方,或者将它们推回到池中以供生产者重用)。这可以避免缓冲区本身的任何锁定,只留下P-C队列上的锁定。问题在于,只有偶尔生成长片的生产者才会处理他们的数据,直到他们的* Buffer被填满,这可能需要一些时间,(在这样的线程中你可以在阵列变满之前推掉缓冲区。) / p>
b)声明一个带有数组的Buffer结构来保存一些long和一个索引。使用互斥锁/ futex / CS锁保护。 malloc()只是一个共享*缓冲区并让所有线程获得锁定,推送它们的长度并释放锁定。如果一个线程推入最后一个数组位置,将* Buffer排队到生产者 - 消费者队列上的消费者线程,立即malloc一个新的* Buffer然后释放锁。消费者获取* Buffers并处理它们然后将它们释放(或者将它们排到其他地方,或者将它们推回池中以供生产者重复使用)。
答案 2 :(得分:1)
您可能需要考虑条件。看一下消费者的这段代码:
while( load == 0 )
pthread_cond_wait( ¬Empty, &mutex );
它的作用是检查加载(存储列表中元素数量的位置)是否为零,如果为零,则等待生产者生成新项目并将其放入清单。
您应该为生产者实现相同的条件(当它想要将项目放入完整列表时)