TStream を受け取るプロシージャを開発しました。ただし、すべてのタイプのストリーム相続人の送信を許可するための基本タイプ。
この手順は、各コアに 1 つのスレッド、または複数のスレッドを作成することを目的としています。各スレッドはストリーム データ (読み取り専用) の詳細な分析を実行します。Pascal クラスは参照によって割り当てられ、値によって割り当てられることはないため、読み取り位置がインターカラーであるため、スレッドの衝突が発生します。
これを修正するには、メモリ内の最後の TStream を 2 倍にして新しい変数を割り当てる手順をすべて実行する必要があります。このようにして、各スレッドが一意の TStream を持つように TStream を十分な数だけ複製できます。非常にスレッド ライブラリ メモリの終了後。
注: 手順は DLL 内にあり、スレッドは機能します。
注 2: 目標は、プロシージャが必要なサービスをすべて実行することです。TStreamだけでなく、TStream の配列を簡単に渡すことができます。でも欲しくない!目的は、サービスが完全に手順によって提供されることです。
これを行う方法はありますか?
ありがとうございました。
添加:
低レベルのアイデアはありましたが、Pascal に関する知識は限られています。
- メモリ内のオブジェクトのアドレスとそのサイズを特定します。
- 元のオブジェクトと同じサイズの新しいアドレスをメモリに作成します。
- コンテンツ (生) オブジェクト全体をこの新しいアドレスにコピーします。
- メモリ内のこの新しいアドレスを指す TStream へのポインタを作成します。
これは機能しますか、それともばかですか?? はいの場合、操作方法は?例 お願いします!
2º 追加:
例として、プログラムが暗号化されたストリームに対してブルート フォース攻撃を実行するとします (適用できないため、単なる例です)。
シーン: 8 コアの CPU で 30GB のファイル:
1º - TMemoryStream:
8 つの TMemoryStream を作成し、各 TMemoryStream のファイルの内容全体をコピーします。これにより、240GB RAM が同時に使用されることになります。私はこの壊れた考えを考えます。さらに、マルチスレッドを使用しないと、処理時間が最速のポイントまで増加します。ファイル全体をメモリに読み込んでロードし、分析を開始する必要がありました。壊れた!
* TMemoryStream の不適切な代替手段は、メモリを占有しないように、ファイルを 100MB/コア (800MB) ずつ TMemoryStream にゆっくりとコピーすることです。したがって、各スレッドは 100MB しか見えず、ファイル全体を完了するまでメモリを解放します。しかし問題は、DLL で Synchronize() 関数が必要になることです。これは、Synchronize () で質問を開くと、うまくいかないことがわかっています。DLL はエラーなしでフリーズし、クラッシュします。
2º - TFileStream:
これは私の意見では悪いです。TStream を取得し、8 つの TFileStream を作成して、各 TFileStream の 30GB をすべてコピーします。ディスク上で 240GB を占有するため、これは大きな値であり、HDD に対してもです。HD での読み取りおよび書き込み時間 (コピー) により、マルチスレッドの実装はシングル スレッドよりも時間がかかることが判明します。壊れた!
結論: 上記の 2 つの方法では、synchronize() を使用して各スレッドをキューに入れ、ファイルを読み取る必要があります。したがって、マルチコア CPU でも、スレッドは同時に動作しません。彼がファイルに同時にアクセスできたとしても (複数の TFileStream を直接作成する)、オペレーティング システムはファイルを一度に 1 つずつ読み取るために依然として enfileiraria スレッドを実行します。HDD は完全にスレッドセーフではないため、彼は 2 つのデータを読み取ることはできません。同時に 。これは HDD の物理的な制限です。ただし、OS のキューイング管理は、手動で synchronize() を実装する場合とは異なり、はるかに効果的であり、潜在的なボトルネックを効率的に減らします。これは、TStream のクローンを作成するという私の考えを正当化するものであり、ファイル アクセス キューを管理するためのすべての作業を SO に任せることになります。何の介入もなしに。
例
上記の例では、8 つのスレッドが同じ Stream を異なる方法で同時に分析する必要があります。スレッドは、提供された Stream の種類を認識していないため、ファイル Stream、インターネットからのストリーム、または小さな TStringStream でさえある可能性があります。メイン プログラムは、1 つのストリアンのみを作成し、構成パラメーターを使用します。簡単な例:
TModeForceBrute = (M1, M2, M3, M4, M5...)
TModesFB = set of TModeForceBrute;
TService = record
stream: TStream;
modes: array of TModesFB;
end;
たとえば、ストリーム M1 のみ、M2 のみ、または両方 [M1、M2] を分析できる必要があります。TModesFB 構成は、ストリームの分析方法を変更します。タスクリストとして機能する配列「modes」の各項目は、異なるスレッドによって処理されます。タスク リストの例 (JSON 表現):
{
Stream: MyTstream,
modes: [
[M1, m5],
[M1],
[M5, m2],
[M5, m2, m4, m3],
[M1, m1, m3]
]
}
注: アナライザーでは [m1] + [m2] <> [m1, m2]。
プログラム内:
function analysis(Task: TService; maxCores: integer): TMyResultType; external 'mydll.dll';
DLL の場合:
// Basic, simple and fasted Exemple! May contain syntax errors or logical.
function analysis(Task: TService; maxCores: integer): TMyResultType;
var
i, processors : integer;
begin
processors := getCPUCount();
if (maxCores < processors) and (maxCores > 0) then
processors := maxCores;
setlength (globalThreads, processors);
for i := 0 to processors - 1 do
// It is obvious that the counter modes in the original is not the same counter processors.
if i < length(Task.modes) then begin
globalThreads[i] := TAnalusysThread.create(true, Task.stream, Task.modes[i])
globalThreads[i].start();
end;
[...]
end;
注: シングル スレッドの場合、プログラムは問題なく動作し、既知のエラーはありません。
各スレッドに特定のタイプの分析を処理してもらいたいのですが、DLL で Synchronize() を使用できません。理解?適切でクリーンなソリューションはありますか?