在计算期间以百分比显示运行状态

时间:2013-08-09 06:15:12

标签: c status presentation

我目前正在编写命令行C程序。我的程序中有大量复杂的循环和计算。这是一个问题,我的程序耗费大约2分钟来完成计算所以我想在计算过程中打印一些东西,以表明它运行良好,否则程序将默默运行2分钟,这似乎太长了用户和他们可能认为它崩溃了。

但是,如果我只是插入一行代码将某些值打印到主循环中,它将显着减慢我的程序(我想这是因为我的代码会等到printf函数对屏幕生效)。

现在我有一个功能但非常难看的解决方案,即每1000个循环打印一次。对我来说,理想情况下,解决此问题的最佳方法是以百分比打印状态并在后台同时运行代码。 (就像在Linux中执行sudo apt-get update

3 个答案:

答案 0 :(得分:1)

您可以拥有事件队列机制。假设您的程序执行操作1,操作2,操作3 ...操作n。在一个线程中运行主程序,而另一个线程在队列上等待处理事件。将事件从主线程发布到侦听器线程。   伪代码

  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.
    }

在单独的侦听器线程

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

       }
       }

您需要拥有此事件 - 使用pthread库可以实现C中的队列实现。

答案 1 :(得分:0)

您可以考虑使用一个整数(或一个非常小的数字的更精确的数据类型),这将是程序所处的状态。当你想增加百分比时,你可以简单地做identifier++。您还需要运行后台进程来检测identifier是否已更改,并调用将新百分比输出到屏幕的函数。

这是一个非常简化的解决方案,可能是逻辑推理的最简单的解决方案,但是有很多方法(以及更加准确/有效的方法)来实现这一点。

答案 2 :(得分:0)

一个简单的单线程解决方案是检查每个x(例如1000)循环迭代,然后达到所需的下一个状态里程碑(例如1%),然后打印出一个语句。可选择检查至少(一半)一秒钟。

#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
}

根据循环迭代所需的时间长短,它可能会或可能不会对性能产生影响。根据经验:如果您的循环执行时间超过20纳秒,那么您可以使用它。

如果您的循环很小,您无法承担额外的分支以获取状态消息,那么

  • 您应该考虑先将代码并行化
  • 您应该将迭代索引放入共享变量中,并每隔(半秒)检查一次状态打印线程并打印状态消息。