2012-01-09 9 views
6

私はグーグルでこれを試しました、答えを見つけることができなかった、ここで検索した、答えを見つけることができませんでした。誰かが、スレッドaからSerial()オブジェクト(pyserial)に書き込むスレッドセーフであるかどうか、スレッドbからの読み取りをブロックするかどうか調べましたか?pyserial - スレッドaからシリアルポートに書き込むことができます。スレッドbからの読み取りをブロックしますか?

私はスレッド同期プリミティブとスレッドセーフなデータ構造を使用する方法を知っていますが、実際にはこのプログラムの現在の形式ではシリアルポートの読み取り/書き込み専用スレッドがあり、スレッドセーフなデータ構造を使用してアプリ内のアクティビティ

私のアプリケーションは、メインスレッドからシリアルポートに書き込むことができ、それから読むことはできませんし、2番目のスレッドのブロッキング読み取りを使用してシリアルポートから読み込むことができます。誰かが本当に私がなぜこれがアプリにとって有益なのかを知りたければ、理由を追加することができます。私の考えでは、Serial()のインスタンスは1つだけで、スレッドBはSerialオブジェクトのブロッキング・リードに座っていますが、スレッドAはSerialオブジェクトのwriteメソッドを使用するのが安全です。

Serialクラスがこのように使用できるかどうかは誰でも知っていますか?

EDIT:答えはプラットフォームに依存する可能性があります。このようなプラットフォームで何か経験があるなら、あなたが取り組んでいるプラットフォームを知っておくと良いでしょう。

編集:1つの応答しかありませんが、他の誰かがこれを試している場合は、あなたの経験で回答を残してください。

答えて

11

私はpyserialでこれを行いました。実際にはリソース仲裁の問題は一切ないので、スレッドからの読み取りと別のスレッドからの書き込みは一般的に問題を引き起こしません。シリアルポートは全二重であるため、読み取りと書き込みは完全に独立して同時に実行できます。

+0

PySerialを使用しましたか?どのプラットフォームで正常に動作しましたか? –

+0

私はWindowsでPySerialを使用していましたが、どのプラットフォームでも動作しない理由を想像することはできません。 – TJD

+0

あなたの経験を共有してくれてありがとう! –

3

私はこの方法でLinux(およびWindows)上で問題なく使用しました。

0

スレッドBを「ブロック読み取り」から「非ブロック読み取り/書き込み」に変更することをお勧めします。スレッドBはあなたのシリアルポート "デーモン"になります。

スレッドAはフレンドリーなユーザーインターフェイスのためにフルスピードで実行することも、リアルタイム操作を実行することもできます。

スレッドAは、シリアルポートに直接書き込むのではなく、スレッドBにメッセージを書き込みます。メッセージのサイズ/頻度が低い場合、メッセージ自体の単純な共有バッファと、新しいメッセージが存在することを示すフラグが機能します。より高いパフォーマンスが必要な場合は、スタックを使用する必要があります。これは実際に送信される多くのメッセージと2つのポインタを蓄積するのに十分な大きさの配列を使用するだけで実際に実装されます。書き込みポインターはスレッドAのみによって更新されます。読み取りポインターはスレッドBによってのみ更新されます。

スレッドBはメッセージを取得してシリアルポートに送信します。シリアルポートはタイムアウト機能を使用する必要があります。これにより、読み取りシリアルポート機能がCPUを解放し、共有バッファをポーリングできるようになります。新しいメッセージがあれば、シリアルポートに送信します。私はその時点でスリープを使用して、スレッドBで使用されるCPU時間を制限します。次に、スレッドBループを読み取りシリアルポート機能にすることができます。シリアルポートのタイムアウトが正常に機能しない場合、USB-RS232ケーブルが抜かれた場合と同様に、スリープ機能は優れたPythonコードとそれほど良くないコードとの違いになります。

+4

2スレッドアプローチの全ポイントは、読者スレッドがrcvをブロックするだけなので、どこにでもポーリングする必要はないということです。 – mikepurvis

関連する問題