如何解决C++中ncurses和std输入/输出之间的冲突

问题描述

我正在开发一个多线程应用程序,其中有一个主线程和一个辅助线程。 辅助线程必须接受用户的输入并将结果提供给主线程,问题在于 std::cin 是一个阻塞函数,这意味着如果主线程停止执行,辅助线程无法执行相同的操作,因为std::cin用户必须输入一些东西才能让程序结束,我想克服这个问题。 所以基本上伪代码是这样的:

std::atomic<bool> interrupt(false);

std::string get_input(){

  std::cout << "Insert a new command: ";
  std::string cmd;
  std::cin >> cmd;
  return cmd;

  }

void kill_main_thread(){

  std::this_thread::sleep_for(std::chrono::milliseconds(5000));
  interrupt = true;

  }
int main() {

  std::thread new_thread (kill_main_thread);     // spawn new thread that calls foo()


  while(1) {

      if ( interrupt ) {
          return 0;
      }

      std::future<std::string> fut = std::async(get_input);
      if ( fut.wait_for(std::chrono::seconds(500)) == std::future_status::timeout ){

          std::string cmd = fut.get();

            
           if ( cmd == "close") {...}
            else if ( cmd == "open") {...}
            else {...}

      }

  }
return 0;
  
}

不幸的是,我无法更改程序的执行流程,因此基于之前的一个问题,我决定使用 PDCurses 库来处理 getch() 的存在,这允许我创建一个非阻塞的输入功能

std::string input(){

    initscr();
    keypad(stdscr,TRUE);
    nodelay(stdscr,TRUE);
    char ch;
    std::string cmd = "";

    while(!interrupt) {
        if ((ch = getch()) != ERR)
            cmd = cmd + ch;

        if ( ch == '\n') break;
    }
    endwin();
    return cmd;
}

以这种方式,通过将这个 input 函数替换为前面示例的 std::cin,通过将中断设置为 true,我可以停止辅助线程的执行。 问题是 PDCurses 与我程序的所有 std::cout 发生冲突,终端无法与标准库一起正常工作。 我找到了三种不同的解决方案来克服这个问题:

1.) 定义一个新终端,我在其中激活 PDCurses,另一个终端必须使用 std。虽然newterm应该创建一个新终端,但此功能不起作用:

    ....
    FILE *f = fopen("/dev/tty","r+");
    SCREEN *screen = newterm(NULL,f,f);
    set_term(screen);
    refresh();
    ....

2.) 仅使用 getch() 函数,避免控制台操作 PDCurses。但我没有找到解决方案。

3.) 以另一种方式定义非阻塞输入函数

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...