Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/unix/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ C++;Unix中的计时器_C++_Unix_Timer - Fatal编程技术网

C++ C++;Unix中的计时器

C++ C++;Unix中的计时器,c++,unix,timer,C++,Unix,Timer,我们有一个处理事件计时器的API。这个API说它使用OS回调来处理定时事件(显然是使用select() api还声明了这种执行顺序: 可读事件 可写事件 计时器事件 其工作原理是创建指向计时器对象的点,但将创建函数传递给函数回调: 大致如下: Timer* theTimer = Timer::Event::create(timeInterval,&Thisclass::FunctionName); 我想知道这是怎么回事? 操作系统正在处理计时器本身,当它看到计时器被触发时,它实际

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

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

其工作原理是创建指向计时器对象的点,但将创建函数传递给函数回调:

大致如下:

Timer* theTimer =  Timer::Event::create(timeInterval,&Thisclass::FunctionName);  
我想知道这是怎么回事?
操作系统正在处理计时器本身,当它看到计时器被触发时,它实际上是如何调用回调的?回调是否在单独的执行线程中运行

当我在回调函数(Thisclass::FunctionName)中调用pthread_self()时,它似乎与创建计时器的线程具有相同的线程id!(对此非常困惑)

还有:上面的优先顺序表是什么意思?什么是可写事件、可读事件和计时器事件

对于在此场景中使用select()的任何解释,我们也将不胜感激


谢谢

猜测一下,对create()的调用将函数指针存储在某处。然后,当计时器关闭时,它调用通过该指针指定的函数。但是,由于这不是一个标准的C++函数,所以你应该真正地阅读文档或者查看源代码来确定。p>
关于你的其他问题,我看不到有人提到优先级列表,而select()是一种通用的事件多路复用器。

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

您应该阅读
选择
投票
——它们非常方便。
通用术语是IO解复用。

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

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


您可以使用(Linux)或(Solaris)等工具来确定操作系统层使用的是哪种机制。这些工具跟踪程序进行的实际系统调用。

很可能有一个框架与典型的主循环一起工作,主循环的驱动力是select调用

选择允许您等待filedescriptor变为可读或可写(或等待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与创建者线程相同,因此我认为它是以某种方式使用信号实现的

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


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

指向相关API文档的链接会有所帮助。如果是内部事务,请阅读源代码;有很多方法可以实现这一点。