2009-06-30 6 views
0

私はシリアルポートを監視し、そのデータを処理する必要があります。テストプログラムとして、私はselectを1つのポートに使用していました。実行機能は次のとおりです。Select()notスレッドで作業中

void <ProtocolClass>::run() 
{ 
    int fd = mPort->GetFileDescriptor(); 
    fd_set readfs; 
    int maxfd=1; 
    int res; 
    FD_ZERO(&readfs); 
    FD_SET(fd,&readfs); 
    struct timeval Timeout; 
    Timeout.tv_usec=0; 
    Timeout.tv_sec=3; 


    //BYTE ack_message_frame[ACKNOWLEDGE_FRAME_SIZE]; 
    while(true) 
    { 
     usleep(10); 
     res=select(maxfd,&readfs,NULL,NULL,NULL); 
     if(res<0) 
      perror("\nselect failed"); 
     else if(res==0) 
       puts("TIMEOUT"); 
     else if(FD_ISSET(fd,&readfs)) 
     {//IF INPUT RECEIVED 
      qDebug("************RECEIVED DATA****************"); 
     FlushBuf(); 
     qDebug("\nReading data into a read buffer"); 
     int bytes_read=mPort->ReadPort(mBuf,1000); 
     mFrameReceived=false; 
     for(int i=0;i<bytes_read;i++) 
     { 
      qDebug("%x",mBuf[i]); 
     } 



     //if complete frame has been received, write the acknowledge message frame to the port. 
     if(bytes_read>0) 
     { 
      qDebug("\nAbout to Process Received bytes"); 
      ProcessReceivedBytes(mBuf,bytes_read); 
      qDebug("\n Processed Received bytes"); 
      if(mFrameReceived) 
     { 
     int no_bytes=mPort->WritePort(mAcknowledgeMessage,ACKNOWLEDGE_FRAME_SIZE); 
      }//if frame received 
     }//if bytes read > 0 
     } //if input received 
    }//end while 
} 

しかし、問題は何も起こらないように思われます。誰かがそれを行う正しい方法を提案することができます。私はスレッドごとに選択を使用したい。これは実現可能か?あなたは私にそれを行うためのサンプルコードを与えることができますか?私はネットを検索しましたが、例は非常に基本的なものであり、主要な機能を含んでいます。 C++固有の例はありません。私は途中でQtスレッドを使用しています。

おかげ

答えて

5

私は何が問題なのか知っていると思います。

FD_ZERO(&readfs); 
FD_SET(fd,&readfs); 

上記の行はwhileループ内にある必要があります。 selectコールは、readFs構造体の 'fd'ビット位置をリセットするためです。したがって、次にselectが呼び出されたときには、ファイル記述子がポーリングする間に、すべてがここでリセットされるので、何を知ることになります。私はstefaanvに同意stefaanvによって提案された補正も

+0

ありがとう、それは働いた。しかし、なぜこれはそうなのですか? – rocknroll

+0

選択コールが確実にブロックされていますか? 私はそうは思わない、それはコードが1つの少なくともatleastを読むためのソリューションフォームstefaanvで動作していたはずですケース あなたはそれをテストすることができますか? whileループでFD_SETを有効にする理由は次のとおりです。 selectコールはreadFs構造体を操作し、利用可能なデータがない場合はfdに対応するビット位置をリセットすることができます。したがって、次回のselect時にはfdに対応するビット位置がオフになります。つまり、selectがあなたのfdをポーリングしないことを意味します。 – Warrior

2

まず最初に私は気づいた:maxfdsは+ 1 うこのヘルプをfdとしなければなりませんか?

+0

その男を試してみましたが、それは動作しませんでした – rocknroll

+0

それは以下の示唆と組み合わせて働いた。ありがとうstefaanv – rocknroll

1

を含めるべき

、あなたは()を選択するために、ファイルディスクリプタ1に渡す必要があります。このため、ファイル記述子でデータを監視することさえできません。また、select()にタイムアウト値を渡したことがないことに気づいたので、何かが利用可能になるまで無期限にブロックしています。