Dou*_*oug 31 c++ io console nonblocking
我正在寻找一种(多平台)方式为我的C++程序执行非阻塞控制台输入,因此我可以在程序不断运行时处理用户命令.该计划还将同时输出信息.
什么是最好/最简单的方法?只要他们使用许可许可证,我就可以使用像boost这样的外部库.
我会通过创建一个单独的线程来实现这一点,该线程调用正常的阻塞IO函数并传递一个回调函数,它在输入时会调用它.你确定你需要做你想说的事吗?
至于同时输出信息,如果用户正在键入一些输入并且你打印了一些内容会发生什么?
使用C ++ 11的示例:
#include <iostream>
#include <future>
#include <thread>
#include <chrono>
static std::string getAnswer()
{
std::string answer;
std::cin >> answer;
return answer;
}
int main()
{
std::chrono::seconds timeout(5);
std::cout << "Do you even lift?" << std::endl << std::flush;
std::string answer = "maybe"; //default to maybe
std::future<std::string> future = std::async(getAnswer);
if (future.wait_for(timeout) == std::future_status::ready)
answer = future.get();
std::cout << "the answer was: " << answer << std::endl;
exit(0);
}
Run Code Online (Sandbox Code Playgroud)
在线编译器:https : //rextester.com/GLAZ31262
我已经在不支持线程或 Boost 的 QNX4.5 上使用select
. 您基本上将select
STDIN 作为要使用的文件描述符传递,并且 select 将在输入新行时返回。我在下面添加了一个简化的示例循环。它是独立于平台的,至少对于类 Unix 系统而言是这样。虽然不确定Windows。
while (!g_quit)
{
//we want to receive data from stdin so add these file
//descriptors to the file descriptor set. These also have to be reset
//within the loop since select modifies the sets.
FD_ZERO(&read_fds);
FD_SET(STDIN_FILENO, &read_fds);
result = select(sfd + 1, &read_fds, NULL, NULL, NULL);
if (result == -1 && errno != EINTR)
{
cerr << "Error in select: " << strerror(errno) << "\n";
break;
}
else if (result == -1 && errno == EINTR)
{
//we've received and interrupt - handle this
....
}
else
{
if (FD_ISSET(STDIN_FILENO, &read_fds))
{
process_cmd(sfd);
}
}
}
Run Code Online (Sandbox Code Playgroud)
非阻塞控制台输入 C++ ?
Ans:在后台线程上执行控制台 IO 并提供线程之间的通信方式。
这是一个完整(但简单)的测试程序,它通过将 io 延迟到后台线程来实现异步 io。
该程序将等待您在控制台上输入字符串(以换行符终止),然后对该字符串执行 10 秒的操作。
您可以在操作进行时输入另一个字符串。
输入 'quit' 使程序在下一个周期停止。
#include <iostream>
#include <memory>
#include <string>
#include <future>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <deque>
int main()
{
std::mutex m;
std::condition_variable cv;
std::string new_string;
bool error = false;
auto io_thread = std::thread([&]{
std::string s;
while(!error && std::getline(std::cin, s, '\n'))
{
auto lock = std::unique_lock<std::mutex>(m);
new_string = std::move(s);
if (new_string == "quit") {
error = true;
}
lock.unlock();
cv.notify_all();
}
auto lock = std::unique_lock<std::mutex>(m);
error = true;
lock.unlock();
cv.notify_all();
});
auto current_string = std::string();
for ( ;; )
{
auto lock = std::unique_lock<std::mutex>(m);
cv.wait(lock, [&] { return error || (current_string != new_string); });
if (error)
{
break;
}
current_string = new_string;
lock.unlock();
// now use the string that arrived from our non-blocking stream
std::cout << "new string: " << current_string;
std::cout.flush();
for (int i = 0 ; i < 10 ; ++i) {
std::this_thread::sleep_for(std::chrono::seconds(1));
std::cout << " " << i;
std::cout.flush();
}
std::cout << ". done. next?\n";
std::cout.flush();
}
io_thread.join();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
示例测试运行:
$ ./async.cpp
first
new string: first 0 1las 2t 3
4 5 6 7 8 9. done. next?
new string: last 0 1 2 3 4 5 6 7 8quit 9. done. next?
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
34244 次 |
最近记录: |