我们有一个处理事件计时器的API。这个API说它使用操作系统回调来处理定时事件(显然是使用select() )。
api还声明了以下执行顺序:可读事件、可写事件、计时器事件
其工作原理是创建一个指向Timer对象的点,但向create函数传递一个函数回调:
大致是这样的:
Timer* theTimer = Timer::Event::create(timeInterval,&Thisclass::FunctionName);
我想知道这是怎么回事?
操作系统本身正在处理计时器,当它看到它被触发时,它实际上是如何调用回调的?回调是否在单独的执行线程中运行?
当我将pthread_self()调用放在回调函数(Thisclass::FunctionName)中时,它看起来与创建theTimer的线程具有相同的线程id!(对此感到非常困惑)
另外:上面的优先级列表是什么意思?什么是可写事件、可读事件和计时器事件?
对select()在此场景中的用法的任何解释也是值得赞赏的。
谢谢!
发布于 2009-08-03 08:09:02
可读事件意味着可以在没有阻塞的情况下读取特定文件描述符上的数据,而可写事件意味着您可以在没有阻塞的情况下写入特定文件描述符。它们最常与插座和管道一起使用。有关这些内容的详细信息,请参阅select()
手册页。
计时器事件表示先前创建的计时器已过期。如果库使用的是select()
或poll()
,则库本身必须跟踪计时器,因为这些函数接受单个超时。库必须计算到第一个计时器超时之前的剩余时间,并将该时间用于超时参数。另一种方法是使用timer_create()
或setitimer()
或alarm()
等较老的变体通过信号接收通知。
您可以使用诸如strace
(Linux)或truss
(Solaris)之类的工具来确定在OS层使用了哪种机制。这些工具跟踪程序正在进行的实际系统调用。
发布于 2009-08-03 07:44:14
在猜测中,对create()的调用将函数指针存储在某个地方。然后,当计时器停止时,它会调用您通过该指针指定的函数。但由于这不是一个标准的C++函数,您应该真正阅读文档或查看源代码以确定答案。
关于您的其他问题,我没有看到提到优先级列表,而select()是一种通用的事件多路复用器。
发布于 2009-08-03 09:24:25
很可能有一个框架与典型的主循环一起工作,主循环的驱动力是select调用。
select允许您等待filedescriptor变为可读或可写(或者等待filedeescriptor上的“异常”),或者等待超时发生。我猜这个库还允许你注册用于异步IO的回调,如果它是一个GUI库,它将通过unixes上的文件描述符获取低级原语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
}
https://stackoverflow.com/questions/1223040
复制相似问题