Link to home
Start Free TrialLog in
Avatar of Øystein Siggerud
Øystein SiggerudFlag for Norway

asked on

Using timers in cpp

Avatar of Eduard Ghergu
Eduard Ghergu
Flag of Romania image

Please, have a look at the chrono header:
https://www.cplusplus.com/reference/chrono/

@Øystein Siggerud

Shall we know your query ?
FYI:
>>  1st Question
>>  Øystein Siggerud asked on 2021-01-18
>>  Please-give-me-a-programming-example-of-setitimer-unix-function-call-in-CPP  => This was resolved.
@Øystein Siggerud

From your given statement:
setitimer.cpp: In member function `void MyClass::registertimer()':
setitimer.cpp:28: error: ISO C++ forbids taking the address of an unqualified or parenthesized non-static member function to form a pointer to member function.  Say `&MyClass::timerevent'
setitimer.cpp:28: error: cannot convert `void (MyClass::*)()' to `void (*)()' in initialization

Open in new window

I tried compiling the same at cygwin at windows
Reproduced your error at cygwin:
your code (29205556_base0.0.cpp)
I am using using iostream and namespace std; => for cygwin.
[code]
#include <iostream>
using namespace std;
#define INTERVAL  2
#include <signal.h>
#include <sys/time.h>

       struct itimerval tout_val;
class MyClass
{
    public :
       void settimer();
       void registertimer();
       void timerevent(void);
    private :
};

void MyClass::settimer()
{
    tout_val.it_interval.tv_sec = 0;
    tout_val.it_interval.tv_usec = 0;
    tout_val.it_value.tv_sec = INTERVAL; /* set timer for "INTERVAL (10) seconds */
    tout_val.it_value.tv_usec = 0;
    setitimer(ITIMER_REAL, &tout_val,0);
}

void MyClass::registertimer()
{
    typedef void(*fp)(void);
    fp ptr = &timerevent;
    signal(SIGALRM,(void(*)(int))ptr); /* set the Alarm signal capture */
}

void MyClass::timerevent(void)
{
     cout<<"timer event"<<endl;
     setitimer(ITIMER_REAL, &tout_val,0);
    //setitimer(ITIMER_REAL, &tout_val,0);
}
int main()
{
    MyClass myclass;
    myclass.settimer();
    myclass.registertimer();
    while(1)
    {
    }
}

Open in new window

ERROR:
/usr/bin/g++ -DCYGWIN_NT -g -O -Wall 29205556_base0.0.cpp -o ./a.out
29205556_base0.0.cpp: In member function ‘void MyClass::registertimer()’:
29205556_base0.0.cpp:29:15: error: cannot convert ‘void (MyClass::*)()’ to ‘fp’ {aka ‘void (*)()’} in initialization
   29 |     fp ptr = &timerevent;
      |               ^~~~~~~~~~
make: *** [Makefile:2: all] Error 1

Open in new window

I have modified your code:
$ diff 29205556_base0.0.cpp 29205556_base0.1.cpp
28c28
<     typedef void(*fp)(void);
---
>     typedef void(MyClass::*fp)(void);
/usr/bin/g++ -DCYGWIN_NT -g -O -Wall 29205556_base0.1.cpp -o ./a.out
29205556_base0.1.cpp: In member function ‘void MyClass::registertimer()’:
29205556_base0.1.cpp:30:34: warning: converting from ‘fp’ {aka ‘void (MyClass::*)()’} to ‘void (*)(int)’ [-Wpmf-conversions]
   30 |     signal(SIGALRM,(void(*)(int))ptr); /* set the Alarm signal capture */
      |                                  ^~~

Open in new window

First Terminal:
$ ./a.out

Second Terminal:
$ kill -s 14 $(ps -eaf | grep a.out | awk '{ print $2}')
First Terminal:
$ ./a.out
timer event
timer event
timer event
timer event


Here "timer event" is repeated even if we do not sent kill signal.
Reason:
      #define INTERVAL  2
Hence
Replace:
      #define INTERVAL  2
With:
      #define INTERVAL  60
or seconds as per your requirement.
Recompile.
/usr/bin/g++ -DCYGWIN_NT -g -O -Wall 29205556_base0.1.cpp -o ./a.out
29205556_base0.1.cpp: In member function ‘void MyClass::registertimer()’:
29205556_base0.1.cpp:30:34: warning: converting from ‘fp’ {aka ‘void (MyClass::*)()’} to ‘void (*)(int)’ [-Wpmf-conversions]
   30 |     signal(SIGALRM,(void(*)(int))ptr); /* set the Alarm signal capture */
      |                    

Open in new window

Retest
First terminal:
$ ./a.out
Second terminal:
$ kill -s 14 $(ps -eaf | grep a.out | awk '{ print $2}')
First terminal:
$ ./a.out
timer event


-Wpmf-conversions:
w Warn
p pointer to
m member
f functions
conversions
Read comment inside the code:
$ cat 29205556_base0.cpp
#ifdef CYGWIN_NT
        #include <iostream>
        using namespace std;
#else
        #include <iostream.h>
#endif
#define INTERVAL 60
#include <signal.h>
#include <sys/time.h>
struct itimerval tout_val;
class MyClass
{
        public:
                void settimer();
                void registertimer();
                void timerevent(int);
        private:
};
void MyClass::settimer()
{
        tout_val.it_interval.tv_sec = 0;
        tout_val.it_interval.tv_usec = 0;
        tout_val.it_value.tv_sec = INTERVAL; /* set timer for "INTERVAL (10) seconds */
        tout_val.it_value.tv_usec = 0;
        setitimer(ITIMER_REAL, &tout_val,0);
        return;
}
void MyClass::registertimer()
{
        // typedef void(MyClass::*fp)(int);
        auto ptr = &timerevent;
        signal(SIGALRM, (void(*)(int)) ptr); /* set the Alarm signal capture */
        return;
}
void MyClass::timerevent(int SIGNUM)
{
        if ( SIGALRM == SIGNUM )
        {
                cout << "timer event SIGALRM" << endl;
        }
        else
        {
                // This will happen when ptr is pointing to member function without an object
                // and without using static member function.
                cout << "timer event: " << (unsigned long)SIGNUM << endl;
        }
        setitimer(ITIMER_REAL, &tout_val,0);
        return;
}
int main()
{
        MyClass myclass;
        myclass.settimer();
        myclass.registertimer();
        while(1)
        {
        }
        return 0;
}

Open in new window

First terminal:
$ ./a.out
Second terminal:
$ kill -s 14 $(ps -eaf | grep a.out | awk '{ print $2}')
First terminal:
$ ./a.out
timer event: 18446744073709536352

Hence handle using static member function.
Duplicate 23722832
This question needs an answer!
Become an EE member today
7 DAY FREE TRIAL
Members can start a 7-Day Free trial then enjoy unlimited access to the platform.
View membership options
or
Learn why we charge membership fees
We get it - no one likes a content blocker. Take one extra minute and find out why we block content.