同时在许多线程上运行TIdHttp的访问冲突 [英] Access Violation with TIdHttp running on many threads at same time

查看:579
本文介绍了同时在许多线程上运行TIdHttp的访问冲突的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在delphi中尝试了一段愤怒的http下载器,但TIdHttpCli只是无法做到我想要的。由于某种原因,它不会在许多线程中同时运行。请仔细看看这个问题:

I'm trying for quite some time to do a "angry http downloader" in delp but TIdHttpCli just cant do what I want. For some reason it won't run at the same time in many threads. Please take a look a the simple demonstration of this problem:

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与Indy交付的XE3。

推荐答案

你有一个多线程的应用程序。为了让内存管理员工作,多线程应用程序必须设置 IsMultiThread True 。如果您的线程基于 TThread

You have a multi threaded application. In order for the memory manager to work, multi-threaded applications must set IsMultiThread to True. This will happen if you base your threads on TThread.

文档


IsMultiThread被设置为True以表示内存管理器应该支持多个线程。 IsMultiThread由BeginThread和类工厂设置为True。

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 。因此,内存管理器假设只有一个线程,并且不锁定对内存管理器的共享数据结构的访问。因此,您观察到的问题。

Because you are calling the raw Windows API CreateThread, and not using the RTL supported thread routines, nothing in the system sets IsMultiThread to True. And so the memory manager assumes that there is only a single thread, and does not lock access to the memory manager's shared data structures. Hence the problems you observed.

如果您在启动时只设置 IsMultiThread:= True ,则代码将正常工作。或者切换到使用 TThread 的线程。

If you simply set IsMultiThread := True at startup, your code will work perfectly. Or switch to using a TThread based thread.

请注意,您的问题与Indy无关。您可以通过在线程中分配堆内存来看到此失败。这个程序每次都在我的系统上死亡:

Note that your issue has nothing at all to do with Indy. You can see this failure simply by allocating heap memory in the thread. This program dies every time on my system:

{$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.

这篇关于同时在许多线程上运行TIdHttp的访问冲突的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆