Delphi 中の回線程
猛禽[メンタルスタジオ]
http://mental.mentsu.com
之五(大结局)
前に戻ってCheckSynchronize、次のページの番号:
関数 CheckSynchronize(タイムアウト: 整数 = 0): ブール値;
変数
SyncPROc: PSyncProc;
LocalSyncList: TList;
始める
If GetCurrentThreadID <> MainThreadID then
raise EThread.CreateResFmt(@SCheckSynchronizeError, [GetCurrentThreadID]);
タイムアウト > 0 の場合
WaitForSyncEvent(タイムアウト)
それ以外
リセット同期イベント;
LocalSyncList := nil;
EnterCriticalSection(ThreadLock);
試す
Integer(LocalSyncList) := InterlockedExchange(Integer(SyncList), Integer(LocalSyncList));
試す
結果 := (LocalSyncList <> nil) および (LocalSyncList.Count > 0);
if 結果 then
始める
LocalSyncList.Count > 0 の場合は実行します
始める
SyncProc := LocalSyncList[0];
LocalSyncList.Delete(0);
LeaveCriticalSection(ThreadLock);
試す
試す
SyncProc.SyncRec.FMethod;
を除外する
SyncProc.SyncRec.FSynchronizeException := AcquireExceptionObject;
終わり;
ついに
EnterCriticalSection(ThreadLock);
終わり;
SetEvent(SyncProc.signal);
終わり;
終わり;
ついに
LocalSyncList.Free;
終わり;
ついに
LeaveCriticalSection(ThreadLock);
終わり;
終わり;
第一に、この方法は、異常が発生するかどうかを確認するために、(前述のように、メッセージを介してプライマリ プロセスに転送される)、プライマリ プロセス内で使用される必要があります。
次に、ResetSyncEvent を使用して調整します (前の SetSyncEvent に対応しており、WaitForSyncEvent の場合は考慮されません。Linux バージョンではバンドル パラメータの CheckSynchronize のみが使用でき、Windows バージョンではチェック パラメータ 0 の CheckSynchronize が使用されます)。
SyncList は、実行されていないすべての同期方法を確認するために使用されます。回線プロセスは非常に多くなる可能性があり、複数の子回線プロセスが同時プロセスを使用している場合、メイン回線プロセスが処理されなくなる可能性があるため、それらを確認するためにリストが必要になります。
同様に、ここでも、SyncList のセキュリティを保護するための基準となる InterlockedExchange を使用して、SyncList を交換します。
LocalSyncList が空でない限り、蓄積されたすべての同期メソッドの処理が 1 サイクルで完了し、最後に処理が完了して、境界領域から退出します。
同期方法の処理をもう一度見てみましょう。最初の同期方法では、まずデータがリスト テーブルから削除され、その後、境界領域から退出します(これも当然、デッド ロックを防ぐためです)。
次に、真の調整を使用する方法です。
同時プロセス中に問題が発生した場合は、キャプチャされて同時プロセスのデータ記録に保存されます。
再び境界領域に入った後、SetEvent を使用してアプリケーション プロセスが通知され、同様のメソッドが実行されます (前述の Synchronize の WaitForSingleObject の使用を参照)。
ここまでで、全体の同期の実現が完了しました。
最後に、次の WaitFor の機能は、次のとおりです。
関数 TThread.WaitFor: LongWord;
変数
H: THandle の配列 [0..1]。
WaitResult: カーディナル;
メッセージ: TMsg;
始める
H[0] := Fハンドル;
GetCurrentThreadID = MainThreadID の場合、
始める
待機結果 := 0;
H[1] := 同期イベント;
繰り返す
{ これにより、バックグラウンド スレッドが実行されている場合に潜在的なデッドロックが防止されます。
フォアグラウンド スレッドに SendMessage を実行します }
if WaitResult = WAIT_OBJECT_0 + 2 then
PeekMessage(メッセージ, 0, 0, 0, PM_NOREMOVE);
WaitResult := MsgWaitForMultipleObjects(2, H, False, 1000, QS_SENDMESSAGE);
CheckThreadError(WaitResult <> WAIT_FAILED);
if WaitResult = WAIT_OBJECT_0 + 1 then
チェック同期;
WaitResult = WAIT_OBJECT_0 になるまで;
end else WaitForSingleObject(H[0], INFINITE);
CheckThreadError(GetExitCodeThread(H[0], Result));
終わり;
メイン ライン プロセスで WaitFor を実行する場合以外は、このライン プロセスを待機する WaitForSingleObject などのハンドルを Signaled 状態に設定するだけで十分です。
メイン ライン プロセスで WaitFor を実行する場合は、まず SyncEvent をハンドル数グループに追加し、その後、ライン プロセスが完了するまで待機します (つまり、MsgWaitForMultipleObjects が WAIT_OBJECT_0 を返します。この API については MSDN で説明されています)。
循環等待機中に次のような処理が行われます。メッセージが発生した場合は、PeekMessage によってこのメッセージが取り出されます (ただし、メッセージ循環中にメッセージが削除されることはありません)。その後、MsgWaitForMultipleObjects を使用して待機中ハンドルまたは同期イベントがシグナル状態になり、同時に通知されます。メッセージ (QS_SENDMESSAGE パラメータ、この API については MSDN の説明を参照)。この API を、同時に複数のハンドルを待機できる WaitForSingle オブジェクトとして使用できます。 + 1)、CheckSynchronize 処理同時メソッドを使用します。
プライマリ プロセスで WaitFor を使用するには、MsgWaitForMultipleObjects を使用する必要がありますが、WaitForSingleObject などでライン プロセスの終了を待つことはできません。これは、在線プロセス関数の実行中のためです。 Synchronize 処理の同期メソッドを使用するように設定することもできますが、このメソッドがメイン プロセスで実行されている場合、WaitForSingleObject などの要求を待っている場合、メイン プロセスはここで起動され、同期メソッドは実行できず、その結果、回線プロセスも起動され、デッドロックが発生します。
まず、WaitForMultipleObjects を使用する場合は、この問題はありません。これは、ライン プロセス ハンドルまたは同期イベント内で 1 つの信号が送信されるだけで、QS_SEND が追加されるまでメイン プロセスを起動できることを示します。 MESSAGE は、Synchronize がメッセージを介してメイン プログラムに送信されるため、メッセージが通信中に妨げられるのを防ぐためのものです。同期中、メイン ライン プロセスは起動され、同期調整を処理し、調整が完了すると、ライン プロセスが終了するまで待機状態になります。
ここまで、オンライン プロセス TThread の分析は 1 つのセグメントの終了を報告することができ、前の分析は 1 つのセグメントとして実行されます。
1、回線プロセスの種類の回線プロセスは通常の方法で終了する必要があります、つまり実行終了を実行する必要があるため、その中のコードに十分な量のコードを追加する必要があります「即座に」終了する必要がある場合は、API または RTL 関数を変更する必要があります。
2. 可視 VCL のアクセスは、同期中にメッセージを通じてメイン プログラムに転送され、メイン プログラムによって処理されます。
3、データを共有するオンラインプログラムのため、このアプリケーション境界領域は保護されています(もちろんSynchronizeも実行されます)。
4、ネットワーク通信はイベントを利用して実行することもできる(もちろんサスペンド/レジュームを利用することもできる)。
5. 複数のオンライン アプリケーションで複数のオンライン プログラムを同時使用する場合は、必ずデッドロックを防止する必要があります。
6、等の待機プロセスを完了するには、WaitFor メソッドを使用します。
12月1日~3日
(终から续完了)