我开发了一个接收 TStream 的程序;但基本类型,允许发送所有类型的流继承者。
此过程旨在为每个内核或多个线程创建一个线程。每个线程都会对流数据进行详细分析(只读),并且由于 Pascal 类是通过引用分配的,而不是按值分配的,因此会有线程冲突,因为读取位置是 intercalará。
为了解决这个问题,我希望该过程完成所有工作,将内存中的最后一个 TStream 加倍,并为其分配一个新变量。这样我可以复制足够数量的 TStream,以便每个线程都有一个唯一的 TStream。非常线程库内存结束后。
注意:程序在 DLL 中,线程工作。
注2:目标是程序做所有必要的服务,即在没有代码干预的情况下调用;您可以轻松地传递一个TStream 数组,而不仅仅是一个 TStream。但我不想要它!目的是服务完全由程序提供。
你知道怎么做吗?
谢谢你。
添加:
我有一个低级的想法,但我对 Pascal 的了解是有限的。
- 确定对象在内存中的地址及其大小。
- 在内存中创建一个与原始对象大小相同的新地址。
- 将整个内容(原始)对象复制到这个新地址。
- 我创建了一个指向 TStream 的指针,它指向内存中的这个新地址。
这会起作用,还是愚蠢?如果是,如何操作?请举例!
2º 加法:
举个例子,假设程序对加密流执行暴力攻击(只是一个例子,因为它不适用):
场景:一个 8 核 CPU 中的 30GB 文件:
1º - TMemoryStream:
创建 8 个 TMemoryStream 并为每个 TMemoryStreams 复制文件的全部内容。这将导致同时使用 240GB RAM。我考虑了这个错误的想法。此外,它会将处理时间增加到最快的程度,而不使用多线程。我将不得不将整个文件读入内存,然后加载,开始分析它。坏了!
* TMemoryStream 的一个不好的替代方法是将文件慢慢复制到 TMemoryStream 中,以 100MB/核心(800MB)为单位,而不是占用内存。所以每个线程看起来只有 100MB,释放内存直到你完成整个文件。但问题是它需要 DLL 中的 Synchronize() 函数,我们知道这不起作用,因为我在Synchronize() 中打开问题 DLL 冻结而没有错误和崩溃
2º - TFileStream:
这在我看来更糟。看,我得到一个 TStream,创建 8 个 TFileStream 并为每个 TFileStream 复制所有 30GB。这很糟糕,因为在磁盘上占用了 240GB,这对于 HDD 来说也是一个很高的价值。HD中的读写时间(复制)将使多线程的实现比单线程更耗时。坏了!
结论: 上述两种方法都需要使用 synchronize() 将每个线程排队以读取文件。因此,即使在多核 CPU 上,线程也不会同时运行。我知道即使他可以同时访问文件(直接创建几个TFileStream),操作系统仍然enfileiraria线程一次读取文件,因为HDD不是真正的线程安全,他不能读取两个数据同时 。这是硬盘的物理限制!但是,与我手动实现 synchronize() 不同,OS 的排队管理更加有效,并有效地减少了潜在瓶颈。这证明了我克隆 TStream 的想法是合理的,它将留下所有管理文件访问队列的工作;没有任何干预——我知道他会比我做得更好。
例子
在上面的例子中,我想让 8 个线程同时不同地分析同一个 Stream,知道线程不知道提供了什么样的 Stream,它可以是一个文件 Stream,一个来自互联网的流,甚至是一个小的 TStringStream。主程序将只创建一个Strean,并带有配置参数。一个简单的例子:
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()。理解?有足够干净的解决方案吗?