首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

c++如何实现精准定时,在线程循环中sleep_for发现唤醒时间比实际sleep时间长十几倍?

在C++中,实现精准定时可以使用std::chrono库。std::chrono库提供了高精度的时间计算和时间间隔操作。

要在线程循环中实现精确的定时,可以使用std::this_thread::sleep_for函数。std::this_thread::sleep_for函数接受一个std::chrono::duration对象作为参数,表示要睡眠的时间。

例如,如果要实现每隔10毫秒执行一次循环,可以使用以下代码:

代码语言:c++
复制
#include<chrono>
#include<thread>

int main() {
    while (true) {
        // 执行任务代码

        // 精确睡眠10毫秒
        std::this_thread::sleep_for(std::chrono::milliseconds(10));
    }
}

在上面的代码中,std::chrono::milliseconds(10)表示要睡眠10毫秒。std::this_thread::sleep_for函数会尽可能精确地睡眠指定的时间。

如果发现std::this_thread::sleep_for函数唤醒时间比实际睡眠时间长,可能是因为操作系统的调度策略或其他因素导致的。可以尝试使用std::this_thread::sleep_until函数,该函数接受一个std::chrono::time_point对象作为参数,表示要睡眠到指定的时间。

例如,如果要实现每隔10毫秒执行一次循环,可以使用以下代码:

代码语言:c++
复制
#include<chrono>
#include<thread>

int main() {
    auto next_wakeup = std::chrono::steady_clock::now() + std::chrono::milliseconds(10);
    while (true) {
        // 执行任务代码

        // 精确睡眠到下一个唤醒时间
        std::this_thread::sleep_until(next_wakeup);

        // 更新下一个唤醒时间
        next_wakeup += std::chrono::milliseconds(10);
    }
}

在上面的代码中,std::chrono::steady_clock::now()表示当前时间,std::chrono::milliseconds(10)表示要睡眠10毫秒。std::this_thread::sleep_until函数会尽可能精确地睡眠到指定的时间。

需要注意的是,由于操作系统的调度策略和其他因素的影响,std::this_thread::sleep_forstd::this_thread::sleep_until函数可能不会完全精确地实现睡眠时间。如果需要更高精度的定时,可以考虑使用操作系统提供的高精度定时器。

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

C++:thread | condition_variable|mutex

C++在这些系统调用接口的基础上,封装出了mutex类。 C++中,mutex(互斥量)是一种同步机制,用于防止多个线程同时访问共享资源,从而避免数据竞争和条件竞争等问题。...线程必须先锁定mutex,这可以通过调用lock()成员函数实现。一旦完成资源访问,线程应该调用unlock()来释放mutex。...以下是一些C++中std::condition_variable相关函数的使用范例: 1. std::condition_variable::wait 这个函数用于阻塞当前线程,直到条件变量被另一个线程唤醒...threads) { th.join(); } return 0; } 3. std::condition_variable::wait_for 这个函数用于定时间内等待条件变量被唤醒...如果指定时间内条件变量没有被唤醒,则返回超时状态。

9810

Linux中的sleep、usleep、nanosleep、poll和select

进行Linux C/C++编程时,可调用的sleep函数有好多个,那么究竟应当调用哪一个了?...下表列出了这几个函数间的异同点,可作为参考: 性质 精准线程安全 信号安全 sleep libc库函数 秒 是 不能和alarm同时使用 有些是基于alarm实现的,所以不能和alarm同时使用...POSIX.1-2001已将usleep标注为废弃,POSIX.1-2008已删除usleep,应当使用nanosleep替代usleep nanosleep 系统调用 纳秒 是 不确定 即使被信号中断,也可实现实际睡眠时长不小于参数指定时长...,如被信号中断,则实际睡眠时长会小于参数指定的时长 ppoll 系统调用 纳秒 是 是 如被信号中断,则实际睡眠时长会小于参数指定的时长 select 系统调用 微秒 是 是 即使被信号中断,也可实现实际睡眠时长不小于参数指定时长...+标准库提供的: 5) 毫秒睡眠 #if __cplusplus >= 201103L #include #include #include std::this_thread::sleep_for

5K40
  • Linux中的sleep、usleep、nanosleep、poll和select

    进行Linux C/C++编程时,可调用的sleep函数有好多个,那么究竟应当调用哪一个了?...下表列出了这几个函数间的异同点,可作为参考: 性质 精准线程安全 信号安全 sleep libc库函数 秒 是 不能和alarm同时使用 有些是基于alarm实现的,所以不能和alarm同时使用...POSIX.1-2001已将usleep标注为废弃,POSIX.1-2008已删除usleep,应当使用nanosleep替代usleep nanosleep 系统调用 纳秒 是 不确定 即使被信号中断,也可实现实际睡眠时长不小于参数指定时长...,如被信号中断,则实际睡眠时长会小于参数指定的时长 ppoll 系统调用 纳秒 是 是 如被信号中断,则实际睡眠时长会小于参数指定的时长 select 系统调用 微秒 是 是 即使被信号中断,也可实现实际睡眠时长不小于参数指定时长...pselect 系统调用 纳秒 是 是 如被信号中断,则实际睡眠时长会小于参数指定的时长 C/C++常用封装: 1) 基于nanosleep的毫秒级封装 #include void

    7.5K20

    c++11 多线程入门教程(一)

    (10) this_thread::sleep_for()就是让此线程休眠,可以传入休眠的时间 this_thread::sleep_for(std::chrono::milliseconds(10...比如,线程可能需要等待某个条件为真才能继续执行,而一个忙等待循环中可能会导致所有其他线程都无法进入临界区使得条件为真时,就会发生死锁。...所以,condition_variable实例被创建出现主要就是用于唤醒等待线程从而避免死锁。...,ref()是传一个引用 std::this_thread::sleep_for(std::chrono::seconds(1)); //线程延时1秒 //给线程传值进去 promise.set_value...推荐标准库用稳定时钟度量时长。若实现用系统时钟代替,则等待时间可能也对时钟调整敏感。 若调用此函数前 valid()== false 则行为未定义。

    93420

    线程同步-The Boost C++ Libraries

    同步保证在任何给定时间只有一个线程可以访问std::cout。 两个线程都尝试写入标准输出流之前获取互斥锁,但是实际上一次仅一个线程访问std::cout。...两种变体仍然环中向标准输出流写入五个数字,但是现在它们使用类boost::unique_lock来锁定互斥体。...调用notify_all()将使用wait()唤醒一直等待此通知的每个线程。 查看print()函数的for循环,您可以看到针对同一条件变量调用了成员函数wait()。...当通过调用notify_all()唤醒线程时,它将尝试获取互斥量,只有fill()函数中成功释放了互斥量之后,该互斥量才会成功。 这里的窍门是,调用wait()还会释放作为参数传递的互斥量。...如果锁不是for循环中的本地锁,而是在外部作用域中实例化的,则示例44.11也适用。实际上,这样做更有意义,因为不需要在每次迭代中都销毁并重新创建锁。

    83410

    C++11『lambda表达式 ‖ 线程库 ‖ 包装器』

    :get_id,所以才能做到谁调用,就获取谁的线程 id 除此之外,this_thread 命名空间中还提供了 线程休眠 的接口:sleep_until、sleep_for sleep_util 表示休眠一个...绝对时间,比如线程运行后,休眠至明天 6::00 才接着运行;sleep_for 则是让线程休眠一个 相对时间,比如休眠 3 秒后继续运行,休眠 绝对时间 用的比较少,这里来看看如何休眠 相对时间 相对时间...,notify_all 表示唤醒所有正在等待中的线程,如果唤醒时,没有线程等待,那就什么都不会发生 条件变量 的使用看似简单,关键在于如何结合具体场景进行设计 2.3.1.交替打印数字 题目要求...某个线程在打印后,条件必定不满足,只能 wait 等待,在这之前会唤醒另一个线程进行打印,因为数字范围全是正数,即只有奇数和偶数两种状态,所以两个线程可以相互配合、相互唤醒,从而达到交替打印的效果 如何确保打印时不会出现非法情况...C++【哈希表的模拟实现C++【初识哈希】 C++【一棵红黑树封装 set 和 map】

    42710

    C++线程知识点汇总

    今天我们来学习一下C++线程相关的所有知识点。...要注意的是,实际开发中,需要注意线程的安全性和正确性,尤其是共享资源的访问问题。使用互斥锁、条件变量等机制可以有效地保护共享资源,避免多线程并发访问导致的问题。...它允许一个或多个线程某个条件成立时被唤醒,并在条件不满足时等待。通常情况下,std::condition_variable 配合 std::mutex 使用,以实现线程间的等待和通知机制。...超时等待:wait_for() 和 wait_until() 函数允许线程定时间内等待条件满足,超时后自动返回。...下面是一个简单的示例代码,演示了如何使用 std::condition_variable 实现线程间的等待和唤醒: #include #include #include

    14410

    Zookeeper C++编程实战之配置更新

    CMainHelper: https://github.com/eyjian/libmooon/blob/master/include/mooon/sys/main_template.h // 演示一个多线程程序如何借助...zookeeper,实现配置的动态更新 // // 实现理念(有些场景不适合): // 1) 让线程不涉及配置的动态更新,这样避免了动态更新配置 // 2) 通过创建新线程的方式达到配置动态更新的目的...,老的线程直接退出 // 3) 先创建新线程,再退出老线程,保持服务不中断 // // 实际上,也可以通过父子进程方式来达到配置动态更新, // 父进程检测到配置更新后,父进程读取配置...(this->is_connected()) break; else std::this_thread::sleep_for..._stop) { // 执行具体的业务逻辑操作,这里仅以sleep替代做示范 std::this_thread::sleep_for(std::chrono::milliseconds

    1.4K30

    C++】C++11的新特性 — 线程库 ,原子操作 , 条件变量

    1 线程 1.1 线程概念 Linux中我们了解了什么是线程: 【Linux】从零开始认识多线程线程概念与底层实现 【Linux】从零开始认识多线程线程控制 【Linux】从零开始认识多线程...实际用法到具体使用时细细研究就好!...notify_all:唤醒所有线程 我们来看一个例子: 我们来实现:两个线程交替打印奇偶数,我们来通过这个了解条件变量: 创建10个线程,都有对应1 - 10 的ID号,每次只能打印一个线程的id,如果...这里我们加入一个计时的接口this_thread::sleep_for(std::chrono::seconds( ))可以进行等待!...\n"; //休眠保证所有线程进入wait this_thread::sleep_for(std::chrono::seconds( 1 )) go();

    18310

    万字长文带你深入理解协程|业界设计和实现的决策分析

    摘要: 讲述C++协程的近况、设计与实现中的细节与决策 C++ 互联网服务端开发方向依然占据着相当大的份额;百度,腾讯,甚至以java为主流开发语言的阿里都在大规模使用C++做互联网服务端开发,今天以...C++为例子,分析一下要支持协程,需要考虑哪些问题,如何权衡利弊,反过来也可以了解到协程适合哪些场景。...这显然是不切实际的。 早期的libgo也使用过共享栈的方式,也正是因为作者实际开发中遇到了这样的问题,才放弃了共享栈的方式。...然后协程B被调度,要等待mtx被解锁才能继续执行下去,由于mtx是协程锁,协程锁在等待时会挂起当前协程而不是阻塞线程,协程Asleep时间结束后会被唤醒并被调度,协程A退出foo函数时会解锁,解锁的行为又会唤醒协程...定时器 libgo框架的主调度器提供了一个基于红黑树的定时器,会在调度线程的主循环中被执行,这样的设计可以与epoll更好地协同工作,无论是定时器还是epoll监听的fd都可以最及时的触发。

    77510

    15分钟让你了解如何实现并发中的Barrier

    所以,我借着这个机会研究了下,发现其实这些多线程/并发中的东西还是蛮有意思的。 阅读本文你可能需要如下的一些知识: 多线程编程的概念。 c++的基本语法和有关多线程的语法。...仔细思考下,是唤醒机制有问题,很明显,如果能够唤醒的时候原子式的唤醒所有的线程,那么上面所说的问题就不存在了。...很多语言里都有这样的方法可以完成上面说的原子性的唤醒所有线程,比如c++里面的notify_all。但是,如果没有这个函数,该如何实现呢?...三、如何运用c++实现Barrier? 虽然上面说了那么多,但是c++实现Barrier不需要这么复杂,这要感谢c++ 11中已经自带了很多原子性的操作,比如上面说的notify_all。...<<endl; } ​ void func3(){ this_thread::sleep_for(chrono::seconds(1)); cout<<"func3"<<endl;

    1.9K30

    【JavaEE初阶】多线程案列之定时器的使用和内部原码模拟

    uu们,本期小编主要是讲解Java标准库中的一个重要的东西即定时器; 1.定时Java标准库中使用方法调用; 2.如何自己idea上直接手搓实现一个定时器的功能模拟; ️2.定时器的使用 2.1使用场景...1.优先级队列为空 问题:我们可以发现当队列为空的时候,现场因该进入阻塞的状态,否则直接执行以下代码释放锁之后,会直接导致释放锁又拿到锁,导致线程饿死 所以这里队列为空的时候我们需要进行线程阻塞,...; 这里不能使用sleep,因为当来新的任务后,线程不能唤醒解锁,导致错过新的任务,如果是continue的话就会循环执行任务那么此时就叫“忙等” 3.7run方法如何执行任务 小编先将代码执行顺序归为一整个...,调用run方法,此时的run方法就是主函数实现的重写任务方法 4.所以我们只需要在线程执行中通过mytimertask的对象,调用这个方法就好了; 如下图所示: ️4.总结 小编本期主要讲解了关于定时...Java标准库中的使用方法,以及自主实现了关于定时器的代码模拟,当然这部分是有一定的难度的,这里涉及到“优先级队列,函数的调用,runnable类的使用,以及比较器的设定,线程安全问题,和唤醒阻塞”相关的知识体系

    6110

    【高并发】高并发场景下如何优化加锁方式?看完这篇我确实明白了!!

    作者个人研发的高并发场景下,提供的简单、稳定、可扩展的延迟消息队列框架,具有精准定时任务和延迟队列处理功能。...自开源半年多以来,已成功为几家中小型企业提供了精准定时调度方案,经受住了生产环境的考验。...当线程执行时,发现条件不满足,是不是可以让线程进入等待状态?当条件满足的时候,通知等待的线程重新执行?...当条件不满足时,如何实现线程等待?当条件满足时,又如何唤醒线程呢? 不错,这是个问题!不过这个问题解决起来也非常简单。简单的说,就是使用线程的等待与通知机制。...实际工作过程中,如果没有特殊的要求,尽量使用notifyAll()方法。因为使用notify()方法是有风险的,可能会导致某些线程永久不会被通知到!

    94820

    【高并发】由InterruptedException异常引发的思考

    作者个人研发的高并发场景下,提供的简单、稳定、可扩展的延迟消息队列框架,具有精准定时任务和延迟队列处理功能。...自开源半年多以来,已成功为几家中小型企业提供了精准定时调度方案,经受住了生产环境的考验。...程序案例 例如,下面的程序代码,InterruptedTask类实现了Runnable接口,run()方法中,获取当前线程的句柄,并在while(true)循环中,通过isInterrupted()方法来检测当前线程是否被中断...,如果当前线程被中断就退出while(true)循环,同时,while(true)循环中,还有一行Thread.sleep(100)代码,并捕获了InterruptedException异常。...既然问题分析清除了,那如何中断线程并退出程序呢?

    65410

    【高并发】面试官:讲讲高并发场景下如何优化加锁方式?

    作者个人研发的高并发场景下,提供的简单、稳定、可扩展的延迟消息队列框架,具有精准定时任务和延迟队列处理功能。...自开源半年多以来,已成功为几家中小型企业提供了精准定时调度方案,经受住了生产环境的考验。...当线程执行时,发现条件不满足,是不是可以让线程进入等待状态?当条件满足的时候,通知等待的线程重新执行?...当条件不满足时,如何实现线程等待?当条件满足时,又如何唤醒线程呢? 不错,这是个问题!不过这个问题解决起来也非常简单。简单的说,就是使用线程的等待与通知机制。...实际工作过程中,如果没有特殊的要求,尽量使用notifyAll()方法。因为使用notify()方法是有风险的,可能会导致某些线程永久不会被通知到!

    40121
    领券