2014年3月10日月曜日

ノンブロッキングでコンソール入力

コンソール入力は通常ブロッキングで行われます
これはscanf等で読み込んだ場合、少なくともEnterを押すまでは処理が停止することを意味します
通常のコンソールプログラミングではコレで問題ありませんが、バックグラウンドで何か処理をしたい場合は困る場合があります

ということでノンブロッキングで読み込む方法
を参考にしました

 11 int CanIRecv(int fd) {
 12     fd_set fdset;
 13     struct timeval timeout;
 14     FD_ZERO(&fdset);
 15     FD_SET(fd, &fdset);
 16     timeout.tv_sec = 0;
 17     timeout.tv_usec = 0;
 18     return(select(fd + 1, &fdset, NULL, NULL, &timeout));
 19 }
 20 
 21 int Recv(int fd, char *buff, int buffSize) {
 22     int i = CanIRecv(fd);
 23     if (i) {
 24         read(fd, buff, buffSize);
 25         buff[strlen(buff) - 1] = '\0';
 26     }
 27     return(i);
 28 }
 29 
 30 int main() {
 31     int cnt = 0;
 32 
 33     while (1) {
 34         char buff[200];
 35         if (Recv(0, buff, sizeof(buff))) {
 36             printf("%d:[%s]\n", cnt, buff);
 37             if (!strcmp(buff, "quit")) { break; }
 38         }
 39         cnt++;
 40     }
 41 
 42     return(0);
 43 }
という感じのコードでテスト
なお<stdio.h>と<sys/time.h>のインクルードが必要

このコードだと文字列の受信はノンブロッキングで行われるため、何も入力しなくてもcntがどんどんインクリメントされていくはずです

結果は
hello
1508070:[hello]
test
2561543:[test]
quit
3515094:[quit]
という感じになり、正常に動作していることが伺えます

ちなみにCanIRecvなどに渡すのはファイルディスクリプタで、POSIXではstdinに0が stdoutに1が stderrに2が割り当てられ、openなどで開くとその後ろが割り当てられます


ということで、マイコンだとよく使ってるノンブロッキングな行入力の使い方でした


MacOSってGCCコンソールでも簡単にネットワークプログラミングができるので、ちょっと遊んでいます
もうちょっと色々できるようになったら XBeeWiFiとか使えば面白いかなーと思っています

0 件のコメント:

コメントを投稿