C ++同时输入和输出到控制台窗口

时间:2011-07-18 17:04:06

标签: c++ asynchronous time io

我正在编写一个服务器(主要用于Windows,但如果我可以保持多平台,那将会很酷)我只是使用一个普通的控制台窗口。但是,我希望服务器能够执行诸如text_to_say_here或kick playername等命令。我怎样才能有异步输入/输出?我已经用普通的printf()和gets_s尝试了一些东西但是这导致了一些非常奇怪的东西。

我的意思是1

感谢。

4 个答案:

答案 0 :(得分:6)

利用C ++ 11功能(即跨平台)的快速代码

#include <atomic>
#include <thread>
#include <iostream>

void ReadCin(std::atomic<bool>& run)
{
    std::string buffer;

    while (run.load())
    {
        std::cin >> buffer;
        if (buffer == "Quit")
        {
            run.store(false);
        }
    }
}

int main()
{
    std::atomic<bool> run(true);
    std::thread cinThread(ReadCin, std::ref(run));

    while (run.load())
    {
        // main loop
    }

    run.store(false);
    cinThread.join();

    return 0;
}

答案 1 :(得分:3)

您可以使用线程模拟异步I / O,但更重要的是,您必须在两个读/写线程之间共享一个互斥锁,以避免线程踩到另一个线程时出现任何问题,并在顶部写入控制台另一个线程的输出。换句话说,std::coutstd::cinfprintf()等不是多线程安全的,因此,您将在两个操作之间获得不可预测的交错模式,其中读取或写入发生在另一个读或写已经发生的时候。您可能很容易在读取过程中尝试进行读取操作,而且,当您在控制台上键入输入时,另一个写入线程可能会开始在控制台上写入,使您看起来很乱我试图输入。

为了正确管理异步读写线程,最好设置两个类,一个用于读取,另一个用于写入。在每个类中,设置一个消息队列,该消息队列将存储消息(很可能是std::string),以便在读取线程的情况下检索主线程,并且主线程在以下情况下将消息推送到写线程。您可能还想创建一个可以打印提示的读取线程的特殊版本,主线程将消息推送到其消息队列中,在从stdinstd::cin读取之前将打印提示。然后,这两个类将共享一个公共互斥锁或信号量,以防止I / O的不可预测的交错。通过在任何iostream调用之前锁定公共互斥锁(之后将其解锁),将避免任何不可预测的I / O交错。每个线程还将添加另一个互斥锁,该互斥锁对于每个线程都是唯一的,可用于维护对该类内部消息队列的访问权限的独占性。最后,您可以将每个类中的消息队列实现为std::queue<std::string>

如果你想让你的程序尽可能跨平台,我建议用Boost :: threads或者使用新的C ++ 0x std :: threads库来实现它。

答案 2 :(得分:1)

如果您放弃控制台窗口并使用TCP连接进行命令和控制,您的服务器将更容易保持多平台,并且更简单,更灵活。

答案 3 :(得分:0)

您可以尝试将输入和输出放在不同的线程上。我不太确定你为什么要这样做,但线程应该做的工作。 :)

http://en.wikibooks.org/wiki/C++_Programming/Threading