Question

I am currently writing a command line C program. There are tons of complex loops and computing in my program. Here comes a problem that my program consumes about 2 minutes to finish computing so I'd like to print something during computing in order to show it is running well, otherwise the programme will run in silence for 2 minutes which seems to be too long for users and they may think it crashes.

However if I simply insert a line of code to print certain values into the main loop, it will slow down my program significantly (I guess it's because my code will wait until the printf function has effect on the screen).

Now I have a functional but really ugly solution i.e. print once every 1000 loops. For me, ideally the best solution for this problem is printing status in percentage and simutanously running the code in the background. (Just like execute sudo apt-get update in Linux)

Was it helpful?

Solution 2

A simple single threaded solution would be to check every x (e.g. 1000) loop iterations wether your desired next status milestone (e.g. 1%) has been reached and print out a statement then. Optionally check wether at least (half) a second has passed.

#include <sys/time.h>

struct timeval last, now;
gettimeofday(&last, NULL);
size_t lastprint = 0;

size_t i;
for (i = 0; i < num_iterations; i++) {
    if (!(i & 0x3FF)) { // every 1024 iterations
        if ( 100 * (i - lastprint) / num_iterations >= 1) { // at least one percent passed
            gettimeofday(&now, NULL);

            if (now.tv_usec - last.tv_usec + (1000000 * (now.tv_sec - last.tv_sec)) > 500000) { // at least half a second passed
                // print status

                last = now;
                lastprint = i;

            }
        }
    }

    // do work
}

Depending on how long a loop iteration takes it may or may not have performance impacts. As a rule of thumb: if your loop takes longer then 20 nanoseconds to execute you will be fine with this.

If your loops are that small that you can't afford to have an extra branch in them for status messages then

  • You should consider parallelising your code first
  • You should put the iteration index into a shared variable and check it with a status printing thread every (half a) second and print status messages like this.

OTHER TIPS

You could have a event-queue mechanism. Say your program does action 1 ,action 2,action 3 .. action n . Run the main program in one thread while the other thread is waiting on queue to process the events. Post events from the main thread to the listener thread. Pseudo-code

  Main thread

   main()
     {
       create(Q);//Q is global
       thread_launch(listener,Q);//Launch the thread with Q as argument
       do_action_1();
       do_action_2();
       ......
       do_action_n();
    }

    do_action_n()
    {
      .....
      post(event,Q);//this event should have some information about the action.
    }

Run this in a separate listener thread

       void ListenerThread(Queue *Q)
       {
       while ( nextEvent(Q,&event))
       {
         switch(event)
         case action1:
         printf("complete %25");
          ...
         case actionn:
          printf("completed");

       }
       }

You need to have this event - Queue implementation in C though which can be achieved by using pthread library.

You could consider having an integer (or a more precise data type for a very small number) that will be the status the program is at. When ever you want to increment the percentage then you could simply do identifier++. You would also need to have a background process running detecting whether identifier has been changed and invoke a function that would output the new percentage to the screen.

This is a very simplified solution and probably the easiest solution to logically deduce, however there are many ways (and much more accurate/efficient ways) to implement this.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top