繁体   English   中英

Unix中的C ++计时器

[英]C++ Timers in Unix

我们有一个处理事件计时器的API。 这个API表示它使用OS回调来处理定时事件(显然使用select())。

api也声明了这个执行顺序:可读事件可写事件计时器事件

这通过创建一个指向Timer对象的点来工作,但是将create函数传递给函数回调:

这些方面的东西:

Timer* theTimer =  Timer::Event::create(timeInterval,&Thisclass::FunctionName);  

我想知道这是如何工作的?
操作系统正在处理计时器本身,当它看到它触发时它是如何实际调用回调的? 回调是否在单独的执行线程中运行?

当我在回调函数(Thisclass :: FunctionName)中放入一个pthread_self()调用时,它看起来与创建游标的线程具有相同的线程ID! (非常困惑)

另外:上面的优先级列表是什么意思? 什么是可写事件vs可读事件vs计时器事件?

在这种情况下对select()的使用的任何解释也是值得赞赏的。

谢谢!

这看起来像是select(2)的简单包装器。 该类保留了一个回调列表,我猜是分别用于读取,写入和计时器到期。 然后有一些类似于dispatchwait调用的地方将文件描述符打包成集合,计算最小超时,并使用这些参数调用select select返回时,包装器可能首先遍历读取集,调用读取回调,然后写入set,然后查看是否有任何定时器已过期并调用这些回调。 这可能发生在同一个线程上,也可能发生在不同的线程上,具体取决于包装器的实现。

你应该阅读selectpoll - 它们非常方便。 一般术语是IO解复用

可读事件意味着数据可用于在不阻塞的情况下读取特定文件描述符,而可写事件意味着您可以在不阻塞的情况下写入特定文件描述符。 这些通常用于插座和管道。 有关这些内容的详细信息,请参见select()手册页。

计时器事件意味着先前创建的计时器已过期。 如果库使用select()poll() ,则库本身必须跟踪定时器,因为这些函数接受单个超时。 库必须计算第一个计时器到期之前剩余的时间,并将其用于超时参数。 另一种方法是使用timer_create()或较旧的变体(如setitimer()alarm()通过信号接收通知。

您可以使用strace (Linux)或truss (Solaris)等工具确定在OS层使用的机制。 这些工具跟踪程序正在进行的实际系统调用。

猜测,对create()的调用将函数指针存储在某处。 然后,当计时器熄灭时,它会通过该指针调用您指定的函数。 但由于这不是标准C ++函数,您应该真正阅读文档或查看源代码以确定。

关于您的其他问题,我没有看到优先级列表的提及,而select()是一种通用事件多路复用器。

很可能有一个框架适用于典型的主循环,主循环的驱动力是选择调用。

select允许您等待文件描述符变为可读或可写(或者对于filedeescriptor上的“异常”)或者发生超时。 我猜这个库还允许你注册用于执行异步IO的回调,如果它是一个GUI库,它将通过unix上的文件描述符获得低原始GUI事件。

要在这样的循环中实现计时器回调,您只需保留计时器的优先级队列,并在选择超时或filedescriptor事件上处理它们。

优先级意味着它在定时器之前处理文件i / o,这本身需要时间,可能导致GUI更新,最终导致GUI事件处理程序运行,或其他任务花费时间服务I / O.

图书馆或多或少都在做

for(;;) {
  timeout = calculate_min_timeout();
  ret = select(...,timeout); //wait for a timeout event or filedescriptor events
  if(ret > 0) {
    process_readable_descriptors();
    process_writable_descriptors();
  }
  process_timer_queue();  //scan through a timer priority queue and invoke callbacks
}  

由于计时器回调中的线程id与创建者线程相同,我认为它是以某种方式使用信号实现的。

当一个信号被发送到一个线程时,线程的状态被保存并且信号处理程序被调用然后调用事件回调。 因此,处理程序在创建者线程中被调用,该线程在信号处理程序返回之前被中断。

也许另一个线程使用select()等待所有计时器,如果计时器到期,它会向创建过期计时器的线程发送一个信号。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM