gpt4 book ai didi

java - 从 std::cin 的非阻塞读取是否与 std::this_thread::sleep_for() 或 std::this_thread::yield() (IPC) 一起工作

转载 作者:太空宇宙 更新时间:2023-11-04 13:26:49 29 4
gpt4 key购买 nike

我在实现过程中遇到了一个具体问题,但找不到解决方案。

我有一个分为两部分的应用程序。一部分是 Java swing GUI。第二部分是一个 C++ 应用程序,它执行所有(耗时的)计算逻辑。这两个进程(在两个方向上)与其输出和输入流进行通信。我现在的问题是,在 C++ 程序的一部分中,我必须等待来自 Java 程序的用户输入。然而,等待似乎是一种阻碍。

当我在 shell 中调用程序时,最完美的是:

std::string inputLine1;
std::cin >> inputLine1;

当使用 Java UI 时,这不起作用(自然),因为从 std::cin 读取是阻塞的,所以当 C++ 应用程序等待输入时,Java 应用程序不能做任何事情。

因此,我采用了另一种读取 std::cin 的方法,它应该(至少在我看来)有效,但我无法使其有效。它是:

std::string inputLine1;
while (true)
{
int c = std::cin.peek();
if (c != EOF)
{
std::cin >> inputLine1;
break;
}
std::this_thread::yield();
}

我还尝试用 yield() 替换该行

std::this_thread::sleep_for(std::chrono::milliseconds(500));

在我看来,这段代码应该按如下方式工作:我查看 std::cin。如果那里有东西,我从 cin 读取它。如果什么都没有,我会放弃并稍后重试。

我知道,yielding 被认为不是一种非常干净的工作方式,但我想使这两个应用程序之间的通信尽可能简单。如果可能,没有第三方库,没有更复杂的概念(如套接字)。

但是,这种方法不起作用,它给出了与第一种方法相同的行为,只是从 std::cin 中读入。 Java 程序变得无响应,两个应用程序似乎都没有做任何事情。

如果在 shell 中调用 C++ 应用程序并且我从键盘提供相同的输入,则 C++ 应用程序可以完美运行,因此问题不应该存在。如果我从 C++ 应用程序中删除所有这些给定的代码片段,Java 应用程序就会响应并正常工作——尽管它显然没有获得所需的输入。

最佳答案

在尝试了很长时间来实现来自 cin 的非阻塞输入之后,我很确定它不可能始终如一地工作。

我目前的解决方案是将阻塞 cin 放入它自己的小线程中,让它做它的事情。

对于这个示例,我稍微简化了我的实现,因为您需要某种线程安全的存储系统。

#include <iostream>
#include <thread>
#include <mutex>
#include <queue>

// Super simple thread safe storage
std::queue<std::string> Database;
std::mutex Padlock;
void PushLine(std::string Line) {
std::unique_lock<std::mutex> Lock(Padlock); (void)Lock;
Database.push(Line);
}
bool IsLineAvailable(void) {
std::unique_lock<std::mutex> Lock(Padlock); (void)Lock;
return !Database.empty();
}
std::string PopLine(void) {
std::unique_lock<std::mutex> Lock(Padlock); (void)Lock;
std::string Line(std::move(Database.front()));
Database.pop();
return Line;
}

// Main function with "non-blocking" input from cin
int main(int argc, char *argv[]) {
(void)argc;
(void)argv;
std::thread InputThread = std::thread([](){
do {
// Ensure the input is as clean as possible
if (std::cin.rdbuf()->in_avail()) {
std::cin.ignore(std::cin.rdbuf()->in_avail());
}
std::cin.clear();

// Get a line, cin will block here.
std::string Line;
std::getline(std::cin, Line);

// If the line is not empty attempt to store it.
if (!Line.empty()) {
PushLine(Line);
}
} while (1);
});

// Detach from the thread, it will never end.
InputThread.detach();

// A job to do.
unsigned int Counter = 0;

// Run your program.
bool Running = true;
while(Running) {
// Perform a job, in this case counting.
Counter++;

// Check for available input
if (IsLineAvailable()) {
// If there is input available, first get it
std::string Line = PopLine();

// Echo it to the terminal
std::cout << "Command: " << Line << std::endl;

// Perform actions based on the command
if (Line == "quit") {
Running = false;
}
else if (Line == "count") {
std::cout << " Count: " << Counter << std::endl;
}
}

// Sleep for a while
std::this_thread::sleep_for(std::chrono::milliseconds(100));
}

// Done.
return 0;
}

关于java - 从 std::cin 的非阻塞读取是否与 std::this_thread::sleep_for() 或 std::this_thread::yield() (IPC) 一起工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33067382/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com