更加精确的定时器:dispatch_source_t

在使用定时器时,我们经常使用NSTimer,但是由于NSTimer会受RunLoop影响,当RunLoop处理的任务很多时,就会导致NSTimer的精度降低,所以在一些对定时器精度要求很高的情况下,应该考虑采用GCD定时器,实现代码如下:

    // 队列(队列时用来确定该定时器存在哪个队列中)
    dispatch_queue_t queue = dispatch_get_main_queue();

    // 创建GCD定时器
    _timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue);

    dispatch_time_t start = dispatch_time(DISPATCH_TIME_NOW, 0 * NSEC_PER_SEC); // 开始时间
    uint64_t interval = 2 * NSEC_PER_SEC; // 时间间隔

    // 设置GCD定时器开始时间,间隔时间
    dispatch_source_set_timer(_timer, start, interval, 0);

    // GCD定时器处理回调方法
    dispatch_source_set_event_handler(_timer, ^{
        NSLog(@"---------%@", [NSThread currentThread]);
    });

    // GCD定时器启动,默认是关闭的
    dispatch_resume(_timer);

    /**
        不使用时,记得销毁dispatch_source_t
        dispatch_source_cancel(_timer);
     */
时间: 2024-10-26 13:26:26

更加精确的定时器:dispatch_source_t的相关文章

非实时系统精确定时器的实现

我们通常使用的系统,不管是linux还是windows,都是非实时系统.非实时系统可以获得很精确的当前时间,甚至可以通过读取cpu的某些寄存器得到以cpu周期计数的时钟,估计除了GPS系统之外足以应付我们日常能够碰到的应用,但是,非实时系统并没有提供精确的定时器实现.如果在linux或者windows系统中使用系统定时器,尽管我们可以创建精度为1ms甚至更小的定时器,但是实际执行的时候可以发现,定时器总是需要几ms甚至十几ms才会被调度一次,而不能达到期望的精度. 通常情况下10ms量级的定时器

内核低分辨率定时器实现

什么是低分辨率定时器 低分辨率定时器可以分为周期性和动态性,这里只讨论周期性.在jiffies小节中知道,linux系统会在每个时钟中断会增加jiffies的值,同时还会去处理到期的定时器.而系统时钟中断的速度取决于HZ的值,如果HZ配置为1000,则每秒会产生1000次时钟中断.如果按照样的话,是不是HZ的值越大越好,其实不然.如果HZ的值越大,则会造成系统的负载也会越大.所以HZ的值一般在每个平台是不一样的.假设HZ=250,那么系统会在每4ms会产生一个时钟中断,然后会去处理超时的定时器.

高性能定时器(转自codeproject)

看了这篇文章, http://www.codeproject.com/Articles/2635/High-Performance-Timer-in-C 很不错的方法,虽然平时很少用到这么精确的定时器,但是这里我产生了一个想法,可以使用这个定时器, 用途: 1. 验证算法(code)执行的效率(时间上) 2.用于某些控制场合,比如需要对精确的时间周期 high-performance timer  class: /// <summary> /// A C# class to provide e

linux定时器

我们常常有设置系统在某一时间执行相应动作的需求,比如设置电脑什么时候自动锁屏,什么时候自动关机,设置应用程序什么时候自动运行,什么时候自动退出.这些与时间相关的功能,都需要依靠操作系统中的定时器来实现. linux中定时器的使用原理很简单,你只需设置一个超时时间和相应的执行函数,系统就会在超时的时候执行一开始设置的函数.超时的概念有点模糊,它指的是你设定一个时间,如果当前的时间超过了你设定的时间,那就超时了.比如说,你设置五分钟后系统自动关机,系统会记住五分钟后的具体时间,也就是当前时间再加上五

OC多线程之GCD ----- 2

dispatch_create生成的Queue不管是并行队列还是串行队列,其优先级都是默认优先级 但是可以用dispatch_set_target_queue来改变队列的优先级 dispatch_set_target_queue(原来的队列, 目标优先级队列) 使用这个函数需要获取两个队列,一个是需要变更优先级的队列,一个是指定优先级的队列(指定优先级的队列可以通过get_global获得) 如果多个串行队列优先级相同,那么这些队列里的任务也会串行执行 dispatch_after函数并不能非常

Select与Epoll比较

一.问题引出 联系区别 问题的引出,当需要读两个以上的I/O的时候,如果使用阻塞式的I/O,那么可能长时间的阻塞在一个描述符上面,另外的描述符虽然有数据但是不能读出来,这样实时性不能满足要求,大概的解决方案有以下几种: 1.使用多进程或者多线程,但是这种方法会造成程序的复杂,而且对与进程与线程的创建维护也需要很多的开销.(Apache服务器是用的子进程的方式,优点可以隔离用户) 2.用一个进程,但是使用非阻塞的I/O读取数据,当一个I/O不可读的时候立刻返回,检查下一个是否可读,这种形式的循环为

epoll和select区别

先说下本文框架,先是问题引出,然后概括两个机制的区别和联系,最后介绍每个接口的用法 一.问题引出 联系区别 问题的引出,当需要读两个以上的I/O的时候,如果使用阻塞式的I/O,那么可能长时间的阻塞在一个描述符上面,另外的描述符虽然有数据但是不能读出来,这样实时性不能满足要求,大概的解决方案有以下几种: 1.使用多进程或者多线程,但是这种方法会造成程序的复杂,而且对与进程与线程的创建维护也需要很多的开销.(Apache服务器是用的子进程的方式,优点可以隔离用户) 2.用一个进程,但是使用非阻塞的I

多路复用select和epoll的区别(转)

先说下本文框架,先是问题引出,然后概括两个机制的区别和联系,最后介绍每个接口的用法 一.问题引出 联系区别 问题的引出,当需要读两个以上的I/O的时候,如果使用阻塞式的I/O,那么可能长时间的阻塞在一个描述符上面,另外的描述符虽然有数据但是不能读出来,这样实时性不能满足要求,大概的解决方案有以下几种: 1.使用多进程或者多线程,但是这种方法会造成程序的复杂,而且对与进程与线程的创建维护也需要很多的开销.(Apache服务器是用的子进程的方式,优点可以隔离用户) 2.用一个进程,但是使用非阻塞的I

Linux I/O 进阶

非阻塞I/O 阻塞I/O对应于低速的系统调用,可能会使进程永远阻塞.非阻塞I/O可以使我们发出open.read.write这样的I/O操作,并使这些操作不会永远阻塞.如果这种操作不能完成,则调用立即错误返回,其表示该操作如果继续执行将会阻塞. 对于一个给定的描述符,有两种为其指定非阻塞I/O的方法: (1)   如果是调用open获得文件描述符,则可指定O_NONBLOCK标志. (2)   对于一个已经打开的文件描述符,则可以调用fcntl,由该函数打开O_NONBLOCK文件状态标志. 如