Does non-blocking read from std::cin work with std::this_thread::sleep_for() or std::this_thread::yield() (IPC)

前端 未结 1 1044
执笔经年
执笔经年 2021-01-25 03:18

I\'ve encountered a specific problem with my implementation and can\'t find a solution for it.

I have a two-part application. One part is a Java swing GUI. The second pa

1条回答
  •  北海茫月
    2021-01-25 03:44

    After trying for a long time to implement non-blocking input from cin, I'm pretty sure it's impossible to getting it to work consistently.

    My current solution is to put the blocking cin into it's own tiny thread and let it do it's thing.

    I've simplified my implementation a little bit for this example, as you need a thread safe storage system of some kind.

    #include 
    #include 
    #include 
    #include 
    
    // Super simple thread safe storage
    std::queue Database;
    std::mutex Padlock;
    void PushLine(std::string Line) {
        std::unique_lock Lock(Padlock); (void)Lock;
        Database.push(Line);
    }
    bool IsLineAvailable(void) {
        std::unique_lock Lock(Padlock); (void)Lock;
        return !Database.empty();
    }
    std::string PopLine(void) {
        std::unique_lock 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;
    }
    

    0 讨论(0)
提交回复
热议问题