1

I have an assignment where i'm supposed to measure some delays between packets without using any CPU or OS clock functions(it may sound dumb, but it makes sense within the virtual network i have to make) and have decided to write my own clock class, similar with how we measure time with microcontrollers using the internal oscillator whose frequency we know.

I began writing a small Clock class that i would make a private member of the TCP class to simply play the role of an internal clock that ticks size_t period times per millisecond. Nothing fancy and accuracy of time measurement is of no importance.

#include <iostream>
#include <cstdio>
#include <thread>

class Clock{
  public:
    Clock();
    ~Clock();
    Clock(const size_t& period);

    size_t getElapsedTime();

    void run();
  private:
    size_t period;
    size_t elapsedTime;
    bool running;
  protected:

};

Clock::Clock() :period(1000000), elapsedTime(0), running(true)
{
    std::thread t(run);
    t.detach();
}

Clock::Clock(const size_t& period) : elapsedTime(0), running(true) {
    this->period = period;
}

void Clock::run() {
    while (this->running){
        for ( int i = 0; i < period; ++i){;}

        ++elapsedTime;
    }
}

Clock::~Clock(){
}

std::size_t Clock::getElapsedTime() {
    return elapsedTime;
}

int main(){

    Clock clk(1000000);

    return 0;
}

The problem i have is that i cannot seem to get this thread to work. I want to have it running non-stop until i destruct the Clock object and when a certain event within the large program happens, i want to call getElapsedTime() and see how long it took for that to trigger.

When writing std::thread t(run); i get an error saying error: invalid use of non-static member function 'void Clock::run()' but making the method static yields even more errors.

beginner420
  • 39
  • 1
  • 7
  • 2
    `for(;;) { /* Do stuff */ }` maybe?? – πάντα ῥεῖ Jan 08 '21 at 11:20
  • First you need to find a computer that runs forever... In all seriousness, `while (true)` is enough, which means so long as `this->running` remains truthful, you're good. – tadman Jan 08 '21 at 11:21
  • The error is telling you that you can't use a non-static member function to start a thread. Why? To call a non-static member function you always need an instance of the respective class. See [this question](https://stackoverflow.com/questions/10673585/start-thread-with-member-function). – Lukas-T Jan 08 '21 at 11:27
  • @churill if i understood that question correctly, i was supposed to write something like `std::thread t(&Clock::run, this);` but doing so gives me `undefined reference to `pthread_create'` – beginner420 Jan 08 '21 at 11:40
  • 1
    You need to look at the documentation of your build system to invoke it in a standard compliant mode. Iirc gcc can be run in a mode that creates programs without threads – Caleth Jan 08 '21 at 11:43
  • @beginner420 Try to link the pthread library (such as by `-lpthread`). – Daniel Langr Jan 08 '21 at 11:46
  • 2
    ...or preferably `-pthread` – Ted Lyngmo Jan 08 '21 at 11:59
  • 1
    This way of measuring time will be extremely unuseful. Your thread runs a busy loop and the clock will run faster on an idle system than on a system under heavy load. Also, use `std::atomic` for variables you read from multiple threads. – Ted Lyngmo Jan 08 '21 at 12:25
  • 2
    If you want the thread to run until you destroy your `Clock` then why not make it a member? It is much harder to clean up a tetached thread. – Galik Jan 08 '21 at 12:28
  • The loop `for ( int i = 0; i < period; ++i){;}` will be optimized away if you use `g++` or `clang++` with `-O2` or `-O3` (which you should use for release builds) so, just remove that loop. – Ted Lyngmo Jan 08 '21 at 12:32
  • 2
    And a small not on security: The lifetime of your thread might be longer than the lifetime of the `Clock`-object that started it, sou might get a danginling pointer and undefined behaviour. – Lukas-T Jan 08 '21 at 12:35
  • @TedLyngmo thanks for the info. I went with this approach as the assignment i'm working on specifically states not to use any OS or CPU time, so i had to find a way to implement my own "clock". I wanted to build this oscillator as i was only interested in something that mimics a clock. – beginner420 Jan 09 '21 at 09:52

1 Answers1

4

You need to pass the Clock to the thread too.

std::thread t(&Clock::run, this);
Caleth
  • 52,200
  • 2
  • 44
  • 75