C で Linux 上でノンブロッキング コンソール I/O を行うにはどうすればよいですか?
-
23-08-2019 - |
質問
C で Linux/OS X 上でノンブロッキング コンソール IO を行うにはどうすればよいですか?
解決
あなたは本当に、しないでください。 TTY(コンソール)がかなり限定された装置であり、あなたはかなりのノンブロッキングI / Oを行うことはありません。あなたは、ノンブロッキングI / Oのようなものを見ていたときに何を、呪い/ ncursesベースのアプリケーションで言う、の生のI / O のと呼ばれています。生のIでは/ O、文字の解釈には消去処理等、ありません代わりに、あなたは他のことをしながらデータをチェックする独自のコードを書く必要があります。
現代のCプログラムでは、のスレッドのまたは軽量プロセスにコンソールI / Oを置くことによって、この別の方法で簡素化することができます。その後、I / Oは、通常のブロッキングの方法で上に行くことができますが、データは別のスレッドで処理されるようにキューに挿入することができます。
更新
ここでhref="http://heather.cs.ucdavis.edu/~matloff/UnixAndC/CLanguage/Curses.pdf" rel="nofollow noreferrer">は、より多くのそれをカバーチュートリアルに呪い
他のヒント
ピートKirkham のと同様に、私は<のhref = "http://cc.byexamples.com/ました20070408 / cc.byexamples.comする> "/」のrel =" noreferrer非ユーザ入力・イン・ループのない-ncursesの遮断性、そしてそれは私のために働きました。問題の良い説明と同様に、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));
}
これは、任意のSTDIN入力関数の前に呼び出す必要があります。私はSTDを使用する場合::この機能を使用する前に、CIN、それが再び真返されることはありません。例えば、)(主は次のようになり、ループを有する
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;
}
この機能は、おそらく)(メインにされている可能性がありますが、私はありませんそれに対して、既存のコードベースで働いています。
私のシステムでは、私が望んでいただけで何だったの改行が送信されるまで、利用可能な入力は、ありませんでした。あなたが入力したとき、すべての文字を読みたい場合は、標準入力の上、「標準的なモード」をオフにする必要があります。 cc.byexamples.com を持っていますそれが動作するはずですので、私は試していないいくつかの提案が、残りは、働いています。
私は例を追加したい:
#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$
私は、「ノンブロッキングユーザーのブックマークncursesのの「今月初めのないループ内の入力は、私は非ブロッキング、非バッファコンソールの入力を必要とするかもしれないと思ったとき、私はしませんでしたので、それが動作するかどうかを保証することはできません。私の使用のために、私は<のhref = "http://www.ibm.com/developerworks/linux/library/l-async/使用して、ユーザは、エンターキーを押しまで、それは入力を取得していないことを気にしませんでした標準入力を読み込むためのindex.html」のrel = "noreferrer"> AIO でます。
ここではC ++を使用して、関連する質問があります - <のhref = "https://stackoverflow.com/questions/315111/cross-platform-linux-win32-nonblocking-c-io-on-stdin-stdout-stderr" >クロスプラットフォーム(Linuxの/ Win32の)標準入力/標準出力/標準エラー出力する
にC ++ IOをノンブロッキングncurses またはスレッドを使用する別の代替方法は、 GNU リードライン, 、具体的には、次のことを可能にする部分です。 コールバック関数を登録する. 。その場合のパターンは次のようになります。
- (他の記述子の中でも) STDIN で select() を使用します。
- select() が STDIN を読み取る準備ができていることを通知したら、readline の rl_callback_read_char() を呼び出します。
- ユーザーが完全な行を入力すると、rl_callback_read_char がコールバックを呼び出します。それ以外の場合は、すぐに戻り、他のコードを続行できます。
あなたが「コンソールIO」によって何を意味するのか全くわからない - あなたはSTDINから読んでいる、またはこれは、いくつかの他のソースからの読み込み、コンソールアプリケーションです。
? あなたはSTDINから読んでいる場合は、は、関数fread()をスキップする必要がありますし、(読み)と(書き込み)、世論調査で()またはブロッキングからのコールを維持するために()を選択し使用します。あなたははsetbuf()で、EOFを返すためにfread起こすべき、入力バッファリングを無効にすることができるかもしれないが、私はそれを試したことがありません。