ポートを同期的に読み書きするときに再帰を回避しますか?


108

Rebol 3のすべてのポート操作は非同期です。同期通信を行うために見つけることができる唯一の方法は、を呼び出すことwaitです。

ただし、この場合の待機の呼び出しの問題は、すべての開いているポートのイベントをチェックすることです(待機に渡されるポートブロックにない場合でも)。次に、応答するイベントハンドラーを呼び出しますが、これらのイベントハンドラーの1つで読み取り/書き込みを実行できます。その結果、「待機」の再帰呼び出しが発生する可能性があります。

どうすればこれを回避できますか?


8
実際、現在のR3実装ではこれに対する解決策はないと思うので、「待機」に「/のみ」の改良を追加しました。これにより、「待機」に提供されたポートでのみ待機します、したがって再帰的な呼び出しを避けます。私のプルリクエストをご覧ください:github.com/rebol/rebol/pull/177
Shixin Zeng

1
好奇心から、なぜ同期する必要があるのですか?
toadzky 2015年

1
同期ポートを使用したコーディングの方がはるかに簡単な状況はたくさんあります。ボタンをクリックするだけでメールを送信し、それが成功したか失敗したかを報告したいとします。それが完了するのを待ってから、他のことを行う方がはるかに簡単です。
Shixin Zeng 2015

1
絶対にRebolを使用する必要がありますか?
Rivenfall、

1
はい。これは実際には、同期通信一般よりもRebol 3に関する質問です。
Shixin Zeng

回答:


1

非同期エントリからすべてのメッセージを受け取り、それらをFIFO(先入れ先出し)として処理する一種の「バッファ」関数を作成してみませんか?

このようにして、ポートの非同期特性を維持し、それらを同期モードで処理できます。


0

非同期イベントのみがあり、同期応答が必要な場合は、タイマーを開始するか、タイムアウトのためにスリープします。ハンドラーまたは必要な目的が満たされた場合はtrueと言って、そうでない場合はfalseにして、イベントがキャンセル/リセットされるようにします。重要な場合も同じです。


0

私は2つの設計上の問題があると思います(おそらく手元のツール/ソリューションに固有の問題)。

  1. Waitやりすぎです- it will check events for all open ports。健全な環境では、待機は必要な場合にのみ実装する必要があります。デバイスごと、ポートごと、ソケットごと...共有リソース間の不要な相互依存関係を作成することは、特に共有リソースを知っている(相互依存関係がなくても)とうまくいきません。多くの問題を引き起こす可能性があります。

  2. イベントハンドラー多すぎる可能性があります。イベントハンドラはできるだけ短くし、イベントのみを処理する必要があります。それ以上の場合は、ハンドラーの処理が多すぎます(特に、他の共有リソースが関係している場合)。多くの場合、ハンドラーはデータを保存するだけです。そうしないと、失われます。非同期ジョブはより複雑なことを行います。


-1

鍵はそのまま使えます。Cummunication1は、グローバルロック状態、つまり変数を設定できます(スレッドセーフであることを確認してください)。locked = true。その後、Communication2はロックが解除されるまで待機できます。

loop do
    sleep 10ms
    break if not locked
end
locked = true
handle_communication()

1
これは実際には、同期通信一般よりもRebol 3に関する質問です。
Shixin Zeng
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.