c++ - 如何在 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.) 以另一种方式定义非阻塞输入函数。
解决方案
推荐阅读
- merge - 避免 Git 对某个文件类型进行任何合并
- python - 如何在没有回溯的情况下在 python 中只引发一个异常?
- c# - 使用 CLI 包装器中的 C++ 函数模板
- c++ - opengl 在 mingw 编译器 netbeans 中找不到库
- networking - 使用 Kubernetes 的直接 pod 网络
- c - 创建字符指针数组
- sql - 在计算不同的列值时使用 Group By
- javascript - 从 Javascript 函数中提取 dataURL
- html - 带有粘性导航栏的 Animated.css
- node.js - 为什么构建目录隐藏在 Netbeans 8.2 node.js 应用程序的项目视图中