C++ wait_for

在看xsens的ROS驱动源码时,遇到了如下代码,其中涉及到了多线程里的wait_for函数:

// Returns empty packet on timeout
RosXsDataPacket XdaCallback::next(const std::chrono::milliseconds &timeout)
{
	RosXsDataPacket packet;

	std::unique_lock<std::mutex> lock(m_mutex);

	if (m_condition.wait_for(lock, timeout, [&] { return !m_buffer.empty(); }))
	{
		assert(!m_buffer.empty());

		packet = m_buffer.front();
		m_buffer.pop_front();
	}

	return packet;
}

wait_for的官方参考资料:http://www.cplusplus.com/reference/condition_variable/condition_variable/wait_for/
std::condition_variable::wait_for的原型有两种:

template <class Rep, class Period>
  cv_status wait_for (unique_lock<mutex>& lck,
                      const chrono::duration<Rep,Period>& rel_time);
template <class Rep, class Period, class Predicate>
       bool wait_for (unique_lock<mutex>& lck,
                      const chrono::duration<Rep,Period>& rel_time, Predicate pred);

我们主要看有谓词pred的版本。wait_for会阻塞所在线程(该线程应当拥有lck),直至超过了rel_time,或者谓词返回true。在阻塞的同时会自动调用lck.unlock()让出线程控制权。对上述行为进行总结:

  1. 只要谓词返回true,立刻唤醒线程;
  2. 当谓词为false,没超时就继续阻塞,超时了就唤醒;
  3. 当其他线程使用notify_one或者notify_all进行唤醒时,取决于谓词的状态,若为false,则为虚假唤起,线程依然阻塞。

回到开始的代码,这一段主要是为了取缓冲区里的数据。若m_buffer里有数据(来自GPS/IMU),则直接返回栈顶,并弹出;若没有数据,则至多等待timeout,超时则会因为assert而报错。

顺便补充下notify_one或者notify_all的区别:
这俩都是condition_variable的成员函数。当执行时,notify_one会唤醒一个等待该变量的线程,但并不指定具体哪一个,notify_all则会唤醒所有等待该变量的线程;如果没有在等待的线程,那就无事发生。

  • 7
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值