【问题标题】:Boost condition variable usage提升条件变量的使用
【发布时间】:2013-08-02 21:34:03
【问题描述】:

我正在尝试实现生产者-消费者模式。我做了功课,但仍然不能确定。实现如下:

boost::mutex m_mutex;
boost::container::deque<T> m_buffer;
boost::condition_variable fifo_loaded;

T pop(void)
{
    boost::mutex::scoped_lock lock(m_mutex);

    while (m_buffer.empty())
    {  
        fifo_loaded.wait(lock); // As i understand, it releases the mutex, 
                                   and whenever it is notified, 
                                   gets it back again   
    }       
    T tmp = m_buffer.front();       
    m_buffer.pop_front();       
    return tmp; 
}


void push(const T &newElem) 
{       
    boost::mutex::scoped_lock lock(m_mutex);        
    m_buffer.push_back(newElem);        
    lock.unlock();      
    fifo_loaded.notify_one();   
}

生产者-消费者对如下所示。可以吗,还是我这里也需要同步?

void produce_thread()
{
    while(true)
    {
        double data = generate_data();  
        m_buffer.push(data);
    }   
}

void consume_thread()
{
    while (true)
    {
        double data = m_buffer.pop();
        process_data(data);
    }
}

void start_system()
{
    boost::thread* thread_a = new boost::thread(capture_thread);
    boost::thread* thread_b = new boost::thread(process_thread);
}

我怎样才能手动停止线程?可以用下面的 bool 来管理它吗?

bool enabled;

void produce_thread()
{
    while(enabled)
    {
        // Do stuff
    }   
}

void consume_thread()
{
    while (enabled)
    {
        // Do stuff
    }
}

【问题讨论】:

  • 你不再需要同步,使用Boost.Atomicboost::atomic&lt;bool&gt;代替bool作为停止标志。

标签: c++ multithreading boost boost-thread condition-variable


【解决方案1】:

您的示例实际上并没有使用您编写的线程安全推送和弹出函数,它直接调用双端队列的推送和弹出函数。如果它确实使用了这些,那么它将是线程安全的,producer_thread/consumer_thread 不需要额外的同步

话虽如此,yohjp 是正确的。您不能只拥有一个不受保护的布尔值,例如“启用”。 C++11 规范将数据速率定义为一个线程能够写入一个值而另一个线程能够读取或写入它的任何时间。此定义与 C++11 之前的编译器使用的定义相匹配(只是使其正式化)。

enabled 需要是一个原子布尔值,例如 boost::atomic,或者您需要一个额外的互斥锁来保护“已启用”,除非您持有互斥锁,否则您无法读取或写入启用的规则。

【讨论】:

  • 我不明白您在第一段中所说的内容,因为我认为我的英语很差。您的意思是我的示例没有使用我自己的 push 和 pop 方法,而是调用 deque 自己的 push 和 pop 吗?但我使用这些:“m_buffer.push(data);” "双数据 = m_buffer.pop();"
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-10-02
  • 2013-01-12
  • 1970-01-01
  • 2023-03-04
  • 2018-10-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多