1

我正在做一些非常繁重和缓慢的科学模拟,我想知道是否有可能让我的程序在用户按下一个键时显示一些关于其状态的信息。

它不需要是可移植的,只适用于linux。

目前,我有这样的代码:

main()
{
    //SOME GLOBAL INITIALIZATIONS

    //this loop is parallelized
    for(i=0;i<max;i++)
    {
        //Some particular to i initializations

        for(j=0;max2;j++)
        {
            // Here are all the slow and ugly calculations
            // the status should be able to be shown when
            // my program is here
        }
    }
    // Final calculations and final data
}

不确定这是否可能,但有时人们可能会认为代码已停止或什么也不做,这可能非常有帮助。

此外,如果无法做到这一点并同时使用 omp,我可以使用更“手动”的并行化。

提前致谢!

4

4 回答 4

1

您可以使用 ncurses 的 getch()

#include <ctype.h>
#include <ncurses.h>
#include <stdio.h>

int keywaiting(int *key) {
  int ch;
  ch = getch();
  if ((ch != ERR) && key) *key = ch;
  return (ch != ERR);
}

int yourprogram(void) {
  int max = 1000, max2 = 1000;
  int i, j;
  int ch;
  /* SOME GLOBAL INITIALIZATIONS */
  /* this loop is parallelized */
  for (i = 0; i < max; i++) {
    /* Some particular to i initializations */
    for (j = 0; j < max2; j++) {
    /* Here are all the slow and ugly calculations */
    /* the status should be able to be shown when */
    /* my program is here */
      printf("%03d%03d\r", i, j);
      if (keywaiting(&ch)) {
        printf("\r\n\r\nAborted @ i = %d; j = %d\r\n", i, j);
        printf("Keypress %d ('%c')\r\n\n", ch, isprint((unsigned char)ch) ? ch : '.');
        printf("Press any key ...");
        refresh();
        i = max;
        j = max2;
      }
    }
  }
  /* Final calculations and final data */
  return 0;
}
int main(void) {
  /* initialize ncurses */
  initscr();
  nodelay(stdscr, TRUE);
  noecho();
  keypad(stdscr, TRUE);
  curs_set(0);

  yourprogram();

  getchar();
  /* done with ncurses */
  clear();
  refresh();
  endwin();

  return 0;
}

不要忘记与 curses 库链接。

于 2013-02-18T19:17:05.983 回答
1

您可以使用该pthreads库:让一个线程等待密钥或任何信号以及何时触发。如果您需要进行一些昂贵的计算来显示输出变量,请使用锁来停止模拟的执行,打印变量并释放锁。不知道这是否可以与 openmp 思想一起使用。

如果您只需要打印变量,那么混合 pthread 和 openmp 应该没有问题。

于 2013-02-18T19:00:48.873 回答
0

好的,感谢您的所有建议。我设法得到了与我想要的相似的东西,它不一样,但会服务(^_^)

这是代码,它只是生成一个等待字符的线程,然后将报告数组从 0“切换”到 1。当每个 omp 线程开始每个“j”迭代时,它们将检查报告并在需要时报告.

#include <stdio.h>
#include <stdlib.h>
#include <omp.h>
#include <pthread.h>
#include <ncurses.h>

unsigned char *report; // this will store whether a thread has to report or not
int max_threads;

void *check_keyboard(void *whatever)
{
    int c;
    int i;

    newterm(NULL,stdin,stdout); // I want to still see the terminal :)
    noecho();
    cbreak();

    while(1)
    {
        if(getch())
        {
            for(i = 0; i < max_threads; i++)
                report[i]=1;
        }
    }

    return NULL;
}

int main(int argc, const char *argv[])
{
    int i,j;
    int tid;
    pthread_t thread0;

    max_threads = omp_get_max_threads();
    report = malloc(max_threads*sizeof(unsigned char));

    pthread_create(&thread0,NULL,check_keyboard,NULL);

#pragma omp parallel private(i,j,tid) shared(report)
    {
    tid = omp_get_thread_num();

#pragma omp for
    for(i = 0; i < 10; i++)
    {
        for(j = 0; j < 10; j++)
        {
#pragma omp critical
            {
            if(report[tid])
            {
                fprintf(stderr,"Hello World from thread %d\n\r",tid);
                fprintf(stderr,"This is iteration i: %d, j: %d\n\r",i,j);
                report[tid] = 0;
            }
            }
            sleep(1); // This 'is' a test for the long and ugly code
        }
    }
    }

    pthread_cancel(thread0);
    pthread_exit(NULL);
    return 0;
}
于 2013-02-19T19:36:27.437 回答
0

这是一个使用信号的示例(但部分用 C++ 编写,信号处理不是):

//ctrl+c to output status, ctrl+z to quit

//#include <iostream> c++ syntax
#include <stdio.h>
#include <signal.h>
volatile sig_atomic_t showStatus = 0;

void signalHandler(int sig){
    if (sig==SIGINT){
        showStatus=1;
    }
    if (sig==SIGTSTP){
        showStatus=2;
    }
}


int main(int argc, char** argv){
    signal(SIGINT,signalHandler);
    signal(SIGTSTP,signalHandler);
    while(true){
        if (showStatus==1){
            showStatus=0;
            //std::cout << "status" << std::endl; c++ syntax
                    printf("status\n");
        }else if(showStatus>1){
            break;
        }

    }

    return 0;

}
于 2013-02-18T18:18:38.053 回答