std::condition_variable::wait_for 的几个细节

文章详细解释了std::condition_variable::wait_for的两个关键点:线程从创建到执行的延迟以及wait_for返回值的含义。线程创建后不会立即执行,其启动时间受CPU状态影响。wait_for的返回值并不直接表示超时,而是predicate_func的返回结果。在设计中通常不需要精确控制线程执行时间,但在测试场景下,可以通过特定方法实现延迟。predicate_func会在wait_for开始和超时或通知后各执行一次。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

std::condition_variable::wait_for 的两种重载用法icon-default.png?t=N2N8https://blog.youkuaiyun.com/smalbig/article/details/130152253

(以下简称上篇)直观上介绍了 std::condition_variable::wait_for 的使用效果,这篇对没解释清楚的注释、执行结果进行解释。

1.线程创建到函数执行的时间

上篇中线程 th

std::thread th(wait_func, wait_time_out);

创建后 wait_func 不会立即执行,原因是创建线程只是程序向系统申请资源的过程,并不保证函数的执行。线程创建到函数执行的时间,受cpu使用状态影响,最佳情况可能需要 3ms。

创建线程后立即给 flag 赋值,会导致上篇中的 predicate_func 在  wait_func  执行时立刻返回true,也就不会进入等待的过程。

	auto predicate_func = [&]() {
		t2 = std::chrono::steady_clock::now();
		if (flag) {
			flag = false;
			return true;
		}
		else {			
			return false;
		}
	};

2.wait_for 返回值的意义

初识 std::condition_variable::wait_for 时,误以为返回值代表是否超时,其实其真正意义是 predicate_func 的返回值。当 flag 为 true 时,即使已经超时,wait_for 也会返回 true,原因是超时后又调用了一次 predicate_func,并把 predicate_func 的返回值作为 wait_for 的返回值返回。

要想让 wait_for 的返回值代表是否超时,就要这样在锁作用域内 notify_one() and flag = true

		{
			std::lock_guard<std::mutex> lck(mu);
			cv.notify_one();
			flag = true;
		}

3.是否有必要精确获知线程在创建时其函数什么时候执行

答案当然是不必要的,应该通过设计来避免这种需求。一般是预先创建线程,其内部函数通过 wait 等待触发。但是在测试时,为了简单起见还是会有这种操作,即线程创建后希望其函数开始执行(或执行到某一步)后才执行后面的代码。在windows平台测试中,为了获得更精确的延时,可以这样:

void LoopDelay(int delay) {
	std::chrono::steady_clock::time_point start = std::chrono::steady_clock::now();
	std::chrono::steady_clock::time_point end;
	while (true) {
		end = std::chrono::steady_clock::now();
		if ((end - start).count() / (1000.f * 1000.f) >= delay)
			break;
	}
}

4.predicate_func的执行时机

bool status = cv.wait_for(lck, std::chrono::milliseconds(wait_time_out), predicate_func);

时执行一次,超时   cv.notify_one() 时执行一次。

std::condition_variable.wait_for()是C++std::condition_variable类的一个成员函数,用于在指定时间内等待条件变量满足特定条件。它的语法如下: ```cpp template< class Rep, class Period > std::cv_status wait_for( std::unique_lock<std::mutex>& lock, const std::chrono::duration<Rep, Period>& timeout_duration ); ``` 其中,`lock`是一个std::unique_lock<std::mutex>对象,用于保护条件变量。`timeout_duration`是一个std::chrono::duration对象,表示等待的时间段。 当调用std::condition_variable.wait_for()时,当前线程会被阻塞,直到以下情况之一发生: 1. 条件变量满足特定条件; 2. 等待时间超过了指定的时间段。 如果等待时间超过了指定的时间段,std::condition_variable.wait_for()会返回std::cv_status::timeout,表示等待超时。 以下是一个使用std::condition_variable.wait_for()的示例代码: ```cpp #include <iostream> #include <thread> #include <condition_variable> std::condition_variable cv; std::mutex mtx; bool ready = false; void worker() { std::this_thread::sleep_for(std::chrono::seconds(2)); std::unique_lock<std::mutex> lock(mtx); ready = true; cv.notify_one(); } int main() { std::cout << "Main thread starts." << std::endl; std::thread t(worker); std::unique_lock<std::mutex> lock(mtx); if (cv.wait_for(lock, std::chrono::seconds(1)) == std::cv_status::timeout) { std::cout << "Timeout occurred." << std::endl; } else { std::cout << "Condition variable is notified." << std::endl; } t.join(); std::cout << "Main thread ends." << std::endl; return 0; } ``` 在上面的示例中,主线程等待1秒钟,如果在1秒钟内没有收到通知,则输出"Timeout occurred.";如果在1秒钟内收到了通知,则输出"Condition variable is notified."。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值