1

RXTXライブラリを使用してデータをシリアルポートに送信しています。データを送信した後、ACKを1秒間待つ必要があります。ArrayBlockingQueueを使用してこの機能を実装しています。

例えば。

val queue = ArrayBlockingQueue(1)

def send(data2Send : Array[Byte]) : Array[Byte]{
   out.write(data2Send)
   queue.poll(1000)
}

def receive(receivedData : Array[Byte]){
  queue.add(receivedData)
}

これは完璧に機能しますが、Scalaを学んでいるので、スレッドとロック構造の代わりにアクターを使用したいと思います。

私の最初の試みは次のとおりです。

class Serial {

sender = new Sender(...)
new Receiver(...).start

class Sender {
      def send(data2Send : Array[Byte]) : Array[Byte]{
       out.write(data2Send)
         receiveWithin(WAIT_TIMEOUT_MILLIS) {
          case response => response
          case TIMEOUT => null
        }
      }
    }

    class Receiver extends Actor{
      def act{
        loop{
           sender ! read()
        }
      }
    }
}

しかし、このコードはjava.lang.AssertionErrorをスローします:アサーションに失敗しました:他のアクターに属するチャネルから受信します。問題は、行為の定義の外で受信や反応を使用できないことだと思います。私がフォローしているアプローチは正しいですか?

2回目の試行:

class Serial {

    new Sender(...).start
    new Receiver(...).start

    def send() = (sender ?! data2Send).asInstanceOf(Array[Byte])

    class Sender {
          def act() {
          loop{
          receive{
           out.write(data2Send)
             receiveWithin(WAIT_TIMEOUT_MILLIS) {
              case response => response
              case TIMEOUT => null
            }
          }
        }
       }
      }

        class Receiver extends Actor{
          def act{
            loop{
               sender ! read()
            }
          }
        }
    }

この2回目の試行では、java.util.NoSuchElementExceptionが発生します。送信者が空のリストの先頭になります。read()行が実行されます。そしてそれははるかに複雑に見えます

4

1 に答える 1

1

NIOを使用していない限り、この状況でのブロックは避けられません。最終的に、メッセージは送信元のソケットから送信されますread()(つまり、どこかのスレッドがブロックする必要があります)。

3つの例を見て(すべてが機能したと仮定しても)、6か月後の午前2​​時にバグを見つけた場合、どのコードスニペットを調べたいと思いますか?どれを選ぶかわかります!

アクターは、イベント駆動型システムで非同期メッセージを送信するのに最適です。ソケットを使用する外部APIをヒットした場合、アクターのようなファサードをそれらの周りにラップして、システムの他の部分と対話できるようにすることができます(これにより、システムの残りの部分が実装の詳細を知ることから保護されます)。いくつかの指針:

  • ソケットへの読み取り/書き込みを処理する必要がある実際のアクターについては、単純にしてください。

  • このアクターとの通信が非同期になるようにシステムを編成してみてください(つまり、他のアクターがブロックして応答を待っていない)

  • Scalaアクターライブラリが間もなく非推奨になることを考えると、私はakkaを使い始めます

于 2012-06-26T22:20:38.780 に答える