- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
我尝试了很长一段时间在 delphi 中做一个“愤怒的 http 下载器”,但是 TIdHttpCli 就是不能做我想做的。由于某种原因,它不会在多个线程中同时运行。请看一下这个问题的简单演示:
procedure HttpRequest(AParam : Integer); stdcall;
var
lHttp: TIdHttp;
begin
lHttp := TIdHttp.Create(nil);
{
lHttp.Get(
'http://stackoverflow.com/questions/15977505/',
TMemoryStream.Create
);
}
end;
procedure TForm1.FormCreate(Sender: TObject);
var
i: Integer;
tid: DWORD;
begin
for i := 0 to 4 do
CreateThread(nil, 0, @HttpRequest, nil, 0, tid);
end;
David Heffernan 编辑:我简化了问题中的代码。此代码仍然显示该行为。我的测试环境是 XE3 和随 XE3 一起交付的 Indy。
最佳答案
您有一个多线程应用程序。为了让内存管理器工作,多线程应用程序必须设置 IsMultiThread
为 True
。如果您的线程基于 TThread
,就会发生这种情况。
来自documentation :
IsMultiThread is set to True to indicate that the memory manager should support multiple threads. IsMultiThread is set to True by BeginThread and class factories.
因为您正在调用原始 Windows API CreateThread
,而不是使用 RTL 支持的线程例程,所以系统中没有任何内容将 IsMultiThread
设置为 True
。因此内存管理器假定只有一个线程,并且不锁定对内存管理器的共享数据结构的访问。因此,您观察到的问题。
如果您在启动时简单地设置 IsMultiThread := True
,您的代码将完美运行。或者切换到使用基于 TThread
的线程。
请注意,您的问题与 Indy 无关。您可以简单地通过在线程中分配堆内存来查看此失败。这个程序每次在我的系统上都会死掉:
{$APPTYPE CONSOLE}
uses
SysUtils, Windows;
function HttpRequest(AParam : Integer): DWORD; stdcall;
var
i: Integer;
P: Pointer;
begin
Result := 0;
for i := 1 to 100000 do
GetMem(P, 1);
end;
var
i: Integer;
tid: DWORD;
begin
try
//IsMultiThread := True;//include this line to make program correct
for i := 0 to 15 do
CreateThread(nil, 0, @HttpRequest, nil, 0, tid);
except
on E:Exception do
Writeln(E.Message);
end;
Readln;
end.
关于multithreading - 同时在多个线程上运行的 TIdHttp 的访问冲突,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15977505/
我是一名优秀的程序员,十分优秀!