GNU/Linux >> Linux の 問題 >  >> Linux

C の Linux でノンブロッキング コンソール I/O を行うにはどうすればよいですか?

例を追加したい:

#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>

int main(int argc, char const *argv[])

{
    char buf[20];
    fcntl(0, F_SETFL, fcntl(0, F_GETFL) | O_NONBLOCK);
    sleep(4);
    int numRead = read(0, buf, 4);
    if (numRead > 0) {
        printf("You said: %s", buf);
    }
}

このプログラムを実行すると、標準入力に入力を提供するのに 4 秒かかります。入力が見つからない場合、ブロックせずに単に戻ります。

2 つの実行例:

Korays-MacBook-Pro:~ koraytugay$ ./a.out
fda 
You said: fda
Korays-MacBook-Pro:~ koraytugay$ ./a.out
Korays-MacBook-Pro:~ koraytugay$ 

Pete Kirkham のように、私は cc.byexamples.com を見つけました。問題の適切な説明と ncurses のバージョンについては、そこにアクセスしてください。

私のコードでは、標準入力またはファイルから初期コマンドを取得し、初期コマンドの処理中にキャンセル コマンドを監視する必要がありました。私のコードは C++ ですが、 scanf() を使用できるはずです そして、C++ 入力関数 getline() を使用する残りの部分 .

肉は、利用可能な入力があるかどうかをチェックする関数です:

#include <unistd.h>
#include <stdio.h>
#include <sys/select.h>

// cc.byexamples.com calls this int kbhit(), to mirror the Windows console
//  function of the same name.  Otherwise, the code is the same.
bool inputAvailable()  
{
  struct timeval tv;
  fd_set fds;
  tv.tv_sec = 0;
  tv.tv_usec = 0;
  FD_ZERO(&fds);
  FD_SET(STDIN_FILENO, &fds);
  select(STDIN_FILENO+1, &fds, NULL, NULL, &tv);
  return (FD_ISSET(0, &fds));
}

これは、標準入力入力関数の前に呼び出す必要があります std::cin を使用した場合 この関数を使用する前は、再び true を返すことはありませんでした。例:main() 次のようなループがあります:

int main(int argc, char* argv[])
{ 
   std::string initialCommand;
   if (argc > 1) {
      // Code to get the initial command from a file
   } else {
     while (!inputAvailable()) {
       std::cout << "Waiting for input (Ctrl-C to cancel)..." << std::endl;
       sleep(1);
     }
     std::getline(std::cin, initialCommand);
   }

   // Start a thread class instance 'jobThread' to run the command
   // Start a thread class instance 'inputThread' to look for further commands
   return 0;
}

入力スレッドでは、新しいコマンドがキューに追加され、jobThread によって定期的に処理されました。 . inputThread このように少し見えました:

THREAD_RETURN inputThread()
{
  while( !cancelled() ) {
    if (inputAvailable()) {
      std::string nextCommand;
      getline(std::cin, nextCommand);
      commandQueue.lock();
      commandQueue.add(nextCommand);
      commandQueue.unlock();
    } else {
        sleep(1);
    }
  }
  return 0;
}

この関数はおそらく main() にあった可能性があります 、しかし、私は既存のコードベースに反対するのではなく、既存のコードベースで作業しています.

私のシステムでは、改行が送信されるまで利用可能な入力はありませんでした。これはまさに私が望んでいたことでした。入力時にすべての文字を読みたい場合は、stdin で「正規モード」をオフにする必要があります。 cc.byexamples.com には、私が試していない提案がいくつかありますが、残りはうまくいったので、うまくいくはずです.


Linux
  1. LinuxコマンドラインからのI/Oレポート

  2. Linux –特定のディレクトリのディスクI / Oを監視する方法は?

  3. Linuxで使用しているシェルを見つける方法

  1. Python で Linux コンソール ウィンドウの幅を取得する方法

  2. Linux でディスク I/O キャッシュをパージする方法は?

  3. C++ を使用して Linux でウィンドウを作成するにはどうすればよいですか?

  1. Linux でコンソールのキーマップを変更するには?

  2. Linux I/O レイテンシーのデバッグ

  3. Linux では、ディスクが断片化されているかどうかをどのように確認しますか?