multithreading - 同时在多个线程上运行的 TIdHttp 的访问冲突

标签 multithreading delphi http

我尝试了很长一段时间在 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。

最佳答案

您有一个多线程应用程序。为了让内存管理器工作,多线程应用程序必须设置 IsMultiThreadTrue。如果您的线程基于 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/

相关文章:

.net - 您是否应该请求 .NET 中的锁定超时?

web-services - 远程客户端无法访问 IIS 7.5 中托管的 Delphi WebService

spring - 使用 spring 和 restful webservice 自定义 HTTP 状态代码

mysql - HTTP 500 - 内部服务器错误 - 部署示例 Tomcat Web 应用程序

iphone - 如何用 Objective C 杀死一个线程?

Java Grande SOR 多线程基准测试

java - 运行多线程卡住 Java

forms - 从基本表单派生的 Delphi 表单

delphi - Delphi Chromium Embedded-清除浏览器缓存

jquery 跨域认证