1

フィールドにTIdTCPServerが含まれているクラスTMasterがあるとします。TMasterクラスの一部のメソッドは、TIdTCPServerのOnExecuteイベントを担当します。

まず、これはスレッドセーフで受け入れられますか?次に、私のクラスに他の多くのプライベートフィールド(名前、日付、その他...)があると仮定しましょう。OnExecuteイベントは、実際にはTMasterクラス内のメソッドであり、これらの変数に安全に書き込むことができますか?

この状況でプライベートフィールドがスレッドセーフかどうかを尋ねるつもりですか?

私は本当に糸脱毛に不慣れであり、どんな助けでも大いに感謝されます!

ありがとう、エイドリアン!

4

2 に答える 2

4

私がこれにアプローチする方法は、イベントで使用されるフィールドを所有者に属させるのTidTCPServer ではなく、カスタムTidContextの子孫を定義してそのクラスにフィールドを追加することです。

次にContextClass、サーバー クラスのプロパティをカスタム コンテキストの型に設定するだけです。このようにして、各接続/スレッドは独自のプライベート フィールドを含む独自のカスタム コンテキストを取得します。このようにして、同じフィールドへの同時スレッド アクセスに問題はありません。

異なるコンテキストからアクセスする必要があるオブジェクトのリストがある場合、2 つのオプションがあります。

1) オブジェクトのコピーを作成し、コンテキスト インスタンスごとにプライベート フィールドに格納します。これは、OnConnectイベントで実行できます。

2) シンクロナイザTIdCriticalSectionTMultiReadExclusiveWriteSynchronizerまたはセマフォなどを使用して、同時スレッド アクセスからオブジェクトを保護します。

どの方法を使用するかは、個々の状況によって異なります。

vcl コンポーネントを操作する必要がある場合は、メインの vcl スレッドの外では安全に実行できないことに注意してください。そのため、独自の子孫を作成する必要がありますtidnotify。を使用してこの種の操作を実行すると、vclsynch 操作の途中で をtidsynch停止するときにデッドロックが発生する可能性があります。tidtcpserver

これは、数年間 Indy を使用して学んだことのほんの一部です。

于 2012-07-25T22:11:12.120 に答える
2

TIdTCPServerマルチスレッドコンポーネントです。何をラップするかに関係なく、OnExecuteイベントは常にワーカー スレッドのコンテキストで (接続されたクライアントごとに 1 つずつ) トリガーされるため、ハンドラー内に配置するコードはすべてスレッド セーフである必要があります。クラスのメンバーは、TMaster同時に複数のスレッドによる同時アクセスから適切に保護する必要があります。

于 2012-07-25T03:57:49.200 に答える