问题描述
我正在开发一个多线程应用程序,其中有一个主线程和一个辅助线程。
辅助线程必须接受用户的输入并将结果提供给主线程,问题在于 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 (将#修改为@)