2009-10-14 98 views
1

我有一个生产者和消费者。生产者在给定的共享内存区域中写入固定大小的项目,并且消费者检索它们。同步生产者和消费者与循环缓冲

随机生产者可能会比消费者明显更慢或更快。

我们想要的是

  1. 如果生产运行非消费者,当它填补了循环缓冲器,它保持高于消费者在消费一个写上历史最悠久的帧(其它快当然 - 我强调这一点,生产者和消费者必须在解决方案中同步,因为它们是不相关的进程)。

  2. 如果消费者比生产者更快,它必须等待一个新的框架并在它出现时消耗它。

我发现生产者/不尊重的第一个请求(即,如果循环缓冲区已满,他们在等待消费者来完成实现消费者循环缓冲器,但唯一的,而我想要覆盖最旧的帧)。

我不想推出我自己的(容易出错)解决方案,但使用预先封装,测试过的解决方案。有人能指点我一个很好的C实现吗? (C++也可以)。

非常感谢。

+0

听起来就像你只是想删除某人必须编码到你看到的实现中的限制。如果你只是删除任何阻止生产者的代码覆盖缓冲区中的数据,我会认为它会像你想要的那样工作。 – 2009-10-14 17:09:04

+0

@Carl - 以及让头部覆盖尾部,您还需要提前尾部指针,否则您所做的只是清空整个缓冲区。 – ChrisW 2009-10-14 17:20:14

+0

@Carl - 不,只是允许生产者覆盖旧的缓冲区,删除信号量将意味着覆盖消费者消费的项目。我需要的是一个同步的生产者消费者实现。 – janesconference 2009-10-14 18:22:36

回答

0

基本上,当消费者速度较慢时,意味着没有人使用缓冲区,因此在删除新框架和覆盖旧框架之间没有区别。所以也许下面的代码可以帮助。生产者RTLock无法锁定缓冲区,因为有消费者使用缓冲区,因此在应用程序级别,您可以指示丢弃这些帧。

class SampleSynchronizer { 

    mutex mux; 

    condition_variable con_cond; 
    unsigned int con_num; 

    condition_variable pro_cond; 
    bool prod; 

public: 

    SampleSynchronizer(): con_num(0), prod(false) { 
    } 

    void consumerLock() { 
    unique_lock<mutex> locker(mux); 
    while(prod) 
     pro_cond.wait(locker); 

    con_num++; 
    } 

    void consumerUnlock() { 
    lock_guard<mutex> locker(mux); 
    con_num--; 
    con_cond.notify_one(); 
    } 

    void producerLock() { 
    unique_lock<mutex> locker(mux); 
    while(con_num > 0) 
     con_cond.wait(locker); 

    prod = true; 
    } 

    bool producerRTLock() { 
    lock_guard<mutex> locker(mux); 
    if(con_num > 0) 
     return false; 

    prod = true; 
    return true; 
    } 

    void producerUnlock() { 
    lock_guard<mutex> locker(mux); 
    prod = false; 
    pro_cond.notify_all(); 
    } 

};