Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/159.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/70.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 当其他线程输出到控制台时,如何防止输入文本中断?_C++_C_Multithreading - Fatal编程技术网

C++ 当其他线程输出到控制台时,如何防止输入文本中断?

C++ 当其他线程输出到控制台时,如何防止输入文本中断?,c++,c,multithreading,C++,C,Multithreading,我有两个线程:其中一个线程不断地向控制台输出某个值,比如说每秒递增一个int值-因此控制台上的每秒钟是1,2,3。。。等等 另一个线程正在等待用户输入-使用命令cin 这是我的问题:当我开始键入某些内容时,当输入int值的时候,我的输入从输入字段中删除,并与int值一起放入控制台。所以当我想输入“hello”时,它看起来是这样的: 1 2 3 he4 l5 lo6 7 8 当其他线程正在向控制台写入时,是否有方法防止我的输入被放入控制台 仅供参考,这是客户端聊天应用程序所需的-一个线程正在侦听

我有两个线程:其中一个线程不断地向控制台输出某个值,比如说每秒递增一个int值-因此控制台上的每秒钟是1,2,3。。。等等

另一个线程正在等待用户输入-使用命令cin

这是我的问题:当我开始键入某些内容时,当输入int值的时候,我的输入从输入字段中删除,并与int值一起放入控制台。所以当我想输入“hello”时,它看起来是这样的:

1
2
3
he4
l5
lo6
7
8
当其他线程正在向控制台写入时,是否有方法防止我的输入被放入控制台


仅供参考,这是客户端聊天应用程序所需的-一个线程正在侦听消息并在消息传入时立即输出消息,另一个线程正在侦听用户输入以发送到服务器应用程序。

如果您打字速度慢,那么您的问题的解决方案可以如我所说,将其设为一个线程,但这可能会使应用程序只有在发送后才能接收


另一种方法是增加接收线程的睡眠时间,这将为您提供更多的键入时间(无中断)

您可以制作一个GUI(如果您确实想在控制台中工作,也可以使用ncurses)。这样可以避免线程共享std::cout。

通常终端本身会回显键入的键。你可以关闭它,让你的程序回显它。这个问题会给你指点怎么做


然后,您可以只获得一个线程来处理输出。

我认为您可以通过一个信号量来解决这个问题。当您收到一条传入消息时,您会检查用户是否在写东西。如果他这样做了,你就等他打印完信息

当其他线程正在向控制台写入时,是否有方法防止我的输入被放入控制台

反之亦然。另一个线程不应该中断您正在键入的内容的显示

假设您键入了“Hel”,然后从另一个线程收到一条新消息。你是做什么的?它应该如何显示

  • 完全禁用键入内容的回显,仅在按enter键后显示。通过这种方式,您可以以原子方式正确显示来自不同线程的消息。最大的缺点是,您无法看到您已经键入的内容…:(

  • 你立即回显你键入的内容。当新消息出现时,你撤销“Hel”,打印新消息,然后在新行上再次打印“Hel”,然后你可以继续键入。这是可行的,但有点难看

  • 您可以在单独的位置回显您键入的内容。也就是说,您可以以某种方式拆分显示。在一个位置,您可以按顺序显示发布/接收的消息;在另一个位置,您可以显示您正在键入的内容。您需要GUI或至少一些控制台库来完成此操作。这将是最好的解决方案,但可能是最难移植的由于库的依赖关系,无法连接到其他操作系统

  • 在任何情况下,您都需要一个(最好是内部)同步流,您可以从不同的线程安全地调用它,并可以将字符串原子地写入其中。也就是说,您需要编写自己的同步流类


    希望这能有所帮助。

    最近我用一个基本的解决方法解决了同样的问题。这可能不是#1解决方案,但对我来说,作为一个新手,它很有魅力

     #include <iostream>    // I/O
     #include <Windows.h>   // Sleep();
     #include <conio.h>     // _getch();
     #include <string>      // MessageBuffer
     #include <thread>      // Thread
     using namespace std;
    
     void ThreadedOutput();
     string MessageBuffer;  // or make it static
    
     void main()
     {
        thread output(ThreadedOutput); // Attach the output thread
        int count = 0;
        char cur = 'a'; // Temporary at start
        while (cur != '\r')
        {
            cur = _getch(); // Take 1 input
            if (cur >= 32 && cur <= 126) // Check if input lies in alphanumeric and special keys
            {
                MessageBuffer += cur; // Store input in buffer
                cout << cur; // Output the value user entered
                count++;
            }
            else if (cur == 8) // If input key was backspace
            {
                cout << "\b \b"; // Move cursor 1 step back, overwrite previous character with space, move cursor 1 step back
                MessageBuffer = MessageBuffer.substr(0, MessageBuffer.size() - 1); // Remove last character from buffer
                count--;
            }
            else if (cur == 13) // If input was 'return' key
            {
                for (int i = 0; i < (signed)MessageBuffer.length(); i++) // Remove the written input
                    cout << "\b \b";
                // "MessageBuffer" has your input, use it somewhere
                MessageBuffer = ""; // Clear the buffer
            }
         }
         output.join(); // Join the thread
     }
    
     void ThreadedOutput()
     {
        int i = 0;
        while (true)
         {
            for (int i = 0; i < (signed)MessageBuffer.length(); i++) // Remove the written input
                cout << "\b \b";
            cout << ++i << endl; // Give parallel output with input
            cout << MessageBuffer; // Rewrite the stored buffer
            Sleep(1000); // Prevent this example spam
         }
     }
    
    #包括//I/O
    #包括//Sleep();
    #包括//_getch();
    #include//MessageBuffer
    #包含//线程
    使用名称空间std;
    void ThreadedOutput();
    string MessageBuffer;//或将其设为静态
    void main()
    {
    线程输出(ThreadedOutput);//附加输出线程
    整数计数=0;
    char cur='a';//开始时是临时的
    而(cur!='\r')
    {
    cur=_getch();//获取1个输入
    
    如果(cur>=32&&cur,那么您唯一能做的就是让系统在您键入/发送消息后才接收消息(将其设置为一个线程,而不是两个线程)@Aswin,但在聊天应用程序中,您只能在发送一条消息后接收消息…没有多大意义:)嗯,这可能是一个解决方案,但您如何检测用户是否正在键入内容?我不知道您是否可以使用cin或scanf进行检测。当我阅读您的问题时,我认为解决方案是为输出和输入提供一个公共缓冲区,并使用一个互斥来控制它。如果用户开始写入,则启用互斥,传入消息必须ait进入缓冲区。当用户按ENTER键或类似键时,互斥锁将被禁用。您每秒打印一次缓冲区或类似键,然后将其清除。