我制作了一个控制台应用程序,它接受来自两个来源的命令:
如果输入了命令,则该命令将存储在向量中,直到另一个while循环(每20ms运行一次)循环通过在所通过的时间内输入的所有命令。如果他读了一个命令,他就会执行它。
现在,有一个Stop命令可以停止应用程序。输入后,应用程序将按预期关闭。但问题是:这需要一些时间,您仍然可以从第一个命令源(getline())输入文本。键入内容后,关闭序列将停止,并等待您按Enter键。
一旦关闭序列开始,我终止第一个线程(包含getline循环)。但这不起作用......
有什么想法吗?
提前致谢!
答案 0 :(得分:0)
getline()
是一个阻塞调用,如果你想从其他线程接收消息(即关闭命令),你可能不得不使用不同的东西。您没有提到您用于多线程的库以及如何终止控制台读取线程(可能,您停止线程的方式仍然不会强制它退出getline
)
这个问题似乎有一些相关的答案:Peek stdin using pthreads
顺便说一句,你提到了一个向量,它是从多个线程访问的(如果我理解的话)。您必须注意正确的同步(例如,在访问向量时使用互斥锁)。
此外,您有某种循环,每20毫秒“轮询”一次向量,这表明您的应用程序整体设计可能存在一些缺陷。尝试通过使用更合适的方法在线程之间传递事件来消除它,例如条件变量。
答案 1 :(得分:0)
问题在于getline
是一个阻止呼叫,在标准输入的情况下,按Enter键后将返回。
我有一个类似的问题,如下所示解决了。
我使用了两个文件描述符:一个用于监视标准输入,另一个用于监视“自管道”。万一发生某些事件,后者会触发解锁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;
}