我制作了一个控制台应用程序,它接受来自两个来源的命令:
如果输入了一条命令,则该命令将存储在向量中,直到另一个while循环(每20毫秒运行一次)通过所输入时间内所有输入的命令循环为止。如果他读取命令,则执行该命令。
现在,有一个Stop命令可以停止应用程序。输入后,应用程序将按预期关闭。但是问题是:这需要一些时间,并且您仍然可以从第一个命令源(getline())输入文本。键入内容后,关机顺序将停止,并一直等到按Enter键。
一旦关闭序列开始,我将终止第一个线程(包含getline循环)。但这不起作用...
有什么想法吗?
提前感谢!
getline()
是一个阻塞调用,如果您想从其他线程接收消息(即关闭命令),则可能必须使用其他方法。您没有提到用于多线程的库以及如何终止控制台读取线程(可能的是,停止线程的方式仍然不会强制其从getline
退出)
这个问题似乎有一些相关的答案:Peek stdin using pthreads
顺便说一句,您提到了一个向量,可以从多个线程访问(如果我理解正确的话)。您必须注意正确的同步(例如,访问向量时使用互斥锁)。
而且,您实际上具有某种循环,该循环每20毫秒对向量进行一次轮询,这表明您可能在应用程序的总体设计中存在一些缺陷。尝试通过使用更合适的方法在线程之间传递事件(例如条件变量)来摆脱它。
问题是,getline
是一个阻止呼叫,如果在标准输入下,按回车键将返回。
我有一个类似的问题,如下所示解决了它。我使用了两个文件描述符:一个用于监视标准输入,另一个用于监视“自管道”。万一发生某些事件,后者会触发解锁select
。前者确保getline
一旦可以读取整行就被调用。
#include <future>
#include <string>
#include <iostream>
#include <thread>
#include <unistd.h>
#include <stdio.h>
#include <sys/select.h>
int pipe_fd[2];
auto p = pipe(pipe_fd);
auto stdin_fd = fileno(stdin); // 0
fd_set check_fd;
int main(int argc, char const *argv[])
{
FD_ZERO(&check_fd);
FD_SET(stdin_fd, &check_fd);
FD_SET(pipe_fd[0], &check_fd);
auto t1 = std::async(std::launch::async, [] {
std::this_thread::sleep_for(std::chrono::seconds(10));
uint32_t dummy = 43;
// this will stop the data input
write(pipe_fd[1], &dummy, sizeof(dummy));
});
auto maxfd = pipe_fd[0] > pipe_fd[1] ? pipe_fd[0] : pipe_fd[1];
select(maxfd + 1, &check_fd, nullptr, nullptr, nullptr);
if (FD_ISSET(stdin_fd, &check_fd))
{
std::string input;
std::getline(std::cin, input);
std::cout << "You enterd:" << input << std::endl;
}
if (FD_ISSET(pipe_fd[0], &check_fd))
std::cout << "Event" << std::endl;
return 0;
}
希望这会有所帮助