我正在尝试在C ++中实现一个回调定时器函数,它应该在超时后进行回调。我正在侦听套接字然后等待它上面的消息。所以如果我有类似getMessages()的东西,我想把它作为参数传递给它。那么如何实现在接收到消息之后,如果在下一个消息到达之前有超时,则启动定时器并发生回调。
我是回调函数的新手。任何帮助是极大的赞赏。谢谢!
答案 0 :(得分:1)
你可能知道,但C ++中没有回调函数这样的东西。但是,函数指针。
函数指针实际上就是 - 指向函数的指针。使用"正常"指针指定指针指向的数据类型(例如int *foo
,char *bar
...);函数指针的工作方式与您指定函数的签名类似:void (*baz)(int)
。请注意,在这种情况下,baz
是指针的名称。
没有代码,我不确定你的计时系统是如何工作的。首先要想到的是一个重复调用的tick函数。您可以定期调用此函数或测量函数调用之间的时间 - 在任何一种情况下您都知道已经过去的时间。递增(或递减)分配的时间变量,当时间到时,使用函数指针触发"回调"。
您可能会觉得有用的一件事是typedef
您的回调函数,如下所示:
typedef void (*Callback)(int)
(同样,Callback
是标识符)。然后你可以像任何其他成员一样定义一个函数(Callback func = foo
)并调用它(func(12)
)。
PS:SE周围点缀的函数指针有很好的资源。 Here's one.
答案 1 :(得分:0)
Here is one approach that I would suggest. You will require 3 different threads for this:
1. First thread is the main processing thread (Th1). It waits for two separate events - either "data on socket" event or "timeout event"
2. Second thread (Th2) will constantly listen on socket ( stay blocked on socket either through select or read call ) and when data appears it will read the data, wrap the data in an event and post it to the first thread.
3. The third thread (Th3) will implement the timer functionality. It will wake up after every 'N' seconds ( where 'N'is timeout interval ) and once it wakes up it will create a timeout event and post it to first thread.
A skeleton of the code would look something like this:
Class Processor
{
public:
// std::list<ProcessorEventBase* > eventQueue;
void init ()
{
// 1. initialize SocketListener and pass address of 'Processor::recvDataOnSocket' function
// 2. initialize TimerUtil and pass address of 'Processor::timeOut' function
// 3. create and run Processor ( Th1 ) thread
// 4. keep the thread waiting on a condition variable
// 5. When thread wakes up, let it fetch event from queue and process it.
}
static void recvDataOnSocket ( char* data, int datalen, void* arg )
{
// typecast arg to Processor
// create a data on socket event
// post it to the 'eventQueue'
// signal the waiting thread
}
static void timeOut ( void* arg )
{
// typecast arg to Processor
// create a timeout event
// post it to event queue
// signal the waiting thread
}
}
class SocketListener
{
public:
void init ( SocketCallback socketCallback)
{
// store the socket Callback
// create a thread to listen on socket ( Th2 )
// when data arrives, call the callback i.e. socketCallback and
// pass data pointer and its size and the stored arguement
}
}
class TimerUtil
{
public:
void init ( TimeoutCallback timeoutCallback, void* arg )
{
// store the timeout Callback
// create a thread that wakes up every 'N' seconds ( Th3 )
// when timer expires, call the callback i.e. timeoutCallback and
// pass the stored argument i.e. arg
}
}
Callback would be something like this:
typedef void (*SocketCallback ) ( char* data, int datalen, void* arg);
typedef void (*TimeoutCallback ) ( void* arg );