【发布时间】:2015-05-27 07:54:57
【问题描述】:
我正在写语音通讯器。我必须从控制台控制程序,因为我们决定不开发 GUI——这并不重要,而且需要时间。所以,有一个线程处理来自控制台的用户命令:
void* ClientApp::commandHandler(void)
{
std::string input;
std::string connPort;
std::string connAddr;
std::map<std::string, int> mapStringValues;
mapStringValues["connect to server"] = 1;
mapStringValues["connect to host"] = 2;
mapStringValues["disconnect from server"] = 3;
mapStringValues["start call"] = 4;
mapStringValues["end call"] = 5;
mapStringValues["set TCP port"] = 6;
mapStringValues["help"] = 7;
mapStringValues["exit"] = 8;
std::cout << "Write command" << std::endl;
//int i = 0;
while(true)
{
//std::cout<< ++i<<std::endl;
std::getline(std::cin, input);
switch(mapStringValues[input])
{
case 1: //connect to server
std::cout << "TODO: connect to server" << std::endl;
break;
case 2: //connect to host
std::cout << "IP:" << std::endl;
std::getline(std::cin, connAddr);
std::cout << "port:" << std::endl;
std::getline(std::cin, connPort);
connectToHost(connAddr, std::stoi(connPort));
break;
case 3: //disconnect from server
std::cout << "TODO: disconnect from server" << std::endl;
break;
case 4: //call
if(callInProgres == true)
{
break;
}
networkController->udpConnect();
startCallViaNet();
break;
case 5: //end call
endCallViaNet();
break;
case 6:
break;
case 7:
showCommands();
break;
case 8:
audioPlayer->stopThread();
audioRecorder->stopThread();
networkController->stopSendUDPThread();
networkController->stopRecvUDPThread();
networkController->stopRecvTCPThread();
networkController->shutdownUdpConnection();
networkController->shutdownTcpConnection();
exit(0);
break;
}
}
}
当我必须接听来电时出现问题。我需要输入,所以我可以写是或否。处理互联网连接调用函数的线程询问并获得答案(是/否)。接下来的操作取决于 acceptCall 函数返回的内容。我知道这会引起麻烦 - 许多线程要求输入。所以为了防止它,在线程调用这个函数之前,它会终止 commandHandler 线程(它是 pthread,我取消它 - 可能不优雅,但工作正常),获取输入然后重新启动 commandHandler:
int ClientApp::acceptCall(std::string ip)
{
std::cout << "Start call from "<<ip<<"? (y/n)" << std::endl;
char c = (char)getchar(); /* std::cin, getline, scanf... - I tied it*/
if(c == 'y'){
return 0;
}
else{
return -1;
}
}
然后当我拒绝呼叫并再次启动 commandHandler 时发生了一些奇怪的事情。 commandHandler 的第一个 getline 不再等待输入。循环开始工作,无法输入。我正在尝试所有可能的输入函数 std::cin.ignore() 和 std::cin.clear() 的所有组合。我成功的最好的方法是在另一个 commandHandler 启动后阻塞 getline,但我的命令与 switch 中的任何情况都不匹配 - 命令是正确的,但没有,除了输入后发生了一个循环循环。我要疯了。我阅读了数百个关于 C++ 输入的线程,但没有任何帮助。
【问题讨论】:
-
您能尝试创建一个Minimal, Complete, and Verifiable Example 并展示给我们看吗?并且还向我们展示了一些导致该行为的实际输入?
-
执行这种情况需要很多代码,我要到下午 6 点才能访问我的计算机:/
标签: c++ multithreading c++11 input console-application