用idhttp 多线程下载网页  
假如 有1000 个页面 需要下载   起10个线程下载  当一个线程 执行完毕 就要有一个新的页面下载线程启动 总要保持当前有 10个线程下载
一直循环 下载完毕  乱了 不知道怎么写了 

解决方案 »

  1.   

    那就创建10个thread吗,每个里面创建一个idhttp,这样可以并行
      

  2.   

    线程 部分 我写好了 也可以下载 
    问题是   我要 起 10 个线程  同时下载  
    一直把 1000 个 网页地址 下载完毕  线程 create 时传入了 页面地址参数 
      

  3.   

    搞个任务丢给Windows的线程池么,管它多少个线程在运行呢,
      

  4.   

    一个 线程  结束后 会有  OnTerminate 事件  mythread.OnTerminate:=MyDone;不是等 10个线程 全部下载完毕 循环检查有线程下载完  如何 循环 计时器 ? 不会吧
      

  5.   

    在线程的ExeCute使用while Not Terminated DO循环调用IDHTTP下载页面不行了嘛?
    一直等到1000个页面都下载完毕.
    没必要使用mythread.OnTerminate:=MyDone;
    这样的话,一直创建IDHTTP和一直释放IDHTTP.
      

  6.   

    搜到一个检查线程状态的函数:
    BOOL GetExitCodeThread(
      HANDLE hThread, // handle to the thread
      LPDWORD lpExitCode // termination status
    );
    If the specified thread has not terminated, the termination status returned is STILL_ACTIVE. If the thread has terminated, the termination status returned may be one of the following:  The exit value specified in the ExitThread or TerminateThread function.  
    The return value from the thread function.  
    The exit value of the thread's process.
    一个 线程 结束后 会有 OnTerminate 事件,在OnTerminate 事件里可以给一个标志线程状态的变量赋值,在OnTerminate 事件里能否创立新的线程?  
      

  7.   

    把1000个url放到urls:Tthreadlist
    每个线程都是死循环:
    while true do
    begin
      if urls空了 then
        break;
      从urls取一个来下载,
      删除这个url,
      然后开始下载
    end;
      

  8.   

    同意楼上的想法,你先把1000个URL放在TStringList里面,比如叫List_URL,设置成互斥资源,也就是在同一时间点只能有一个线程访问这个List_URL,访问前加锁,访问完解锁
    while true do
    begin
    LockList;
      if List_URL.count=0 then
        break;
      从urls取一个来下载,
        删除这个url,
    UnLockList;  然后开始下载
    end;
    //LockList,UnLockList是你自己定义加锁解锁过程
    先定义一个锁
    Var
      Flock:TRTLCriticalSection;.....
    InitializeCriticalSection(Flock);//初始化锁,这样才能用Procedure LockList;
    begin
    EnterCriticalSection(FLock);//进入锁,别的线程执行到的时候会排队等待前面的线程解锁
    end;Procedure UnLockList;
    begin
     LeaveCriticalSection(FLock);
    end;
      

  9.   

    我目前 再 线程的  OnTerminate  事件判断  当一个线程结束时 会触发这个事件 然后再起一个线程 这样是否可以保证线程数不变 ?目前我是放一个 memo 里  如果不加锁访问取url  后果是什么 
    我没加锁 
      

  10.   

    不断的开启线程太费资源了,就像楼上某层说的那样,建个URL队列,每个线程都循环取队列里面的内容,取了后就直接删除队列里面的内容,如果下载失败,把失败的下载加到队列后面,直到队列为空,释放线程对象。有点类似SPOOL技术。
    具体的你可以去看下操作系统原理中关于多任务管理方面的内容,很相近的。
      

  11.   

    直接在While not terminated do里一直循环使用就可以了,简单的多线程程序没必要使用线程池
    在循环里设置一个全局变量表示URL的数值,得到一个页面的源码后,使这个全局变量+1(此时使用临界保护)在循环里判断一下这个值是否大于了现有的URL数值,如果大于了就跳出循环
      

  12.   


    我是这么创建的 
      for i := 0 to 9 do  //10个线程 启动
      begin
        mythread := THtmlThreade.Create(Memo_url.Lines.Strings[i], 'isb', GT_Session,mmo1,  Memo1, Label1);
        mythread.OnTerminate := MyDone;
        mythread.Resume;
      end;
    另外 再线程里用到  CoInitializeEx  单个线程任务 执行时间很短  运行时间长了 会报Out Of Memory  存储空间不足 无法完成此操作   程序关闭是线程内代码造成的 还是 主线程里反复创建子线程造成的 
      

  13.   

    URL放在一个队列里,存取由一个对象进行管理.URL管理对象的工作很简单:接受任务申请,并返回任务.此申请是需要加锁的,同一时间只能有一个线程调用.申请过程需要提供一个"上一次任务ID",当这个ID有效时,从URL队列里删除相应的URL;如果无效当然就不用删除了.返回一个状态值,以标志是否还有任务.线程的工作内容:一,向URL管理对象申请任务,参数为上一次执行完成的任务ID.如果没有任务可申请,结束线程.二,执行申请到的任务.三,任务完成后,跳到<一>继续执行.
    这样你的程序结构会非常简单...也许代码也没多少:)
      

  14.   

    又见 嗷嗷老马  有幸呀 内存泄露 找到了  是线程内用到com  需要手动释放 
    目前  我就是 terminated 里 起线程  结束一个 起一个 保持平衡 凑合用吧
      

  15.   

    我最近也在为这个问题犯愁,但是我看到了一种解决办法,不是一个线程完成后就让线程结束,而是向主程序发送消息,用SendMessage 然后在主程序里对这个消息进行响应,响应函数是关键,SendMessage后子线程不要退出,让主程序决定,主程序重新对其装订下载参数,然后再次让该子线程进行下载,这样就不需要再动态创建新的线程,直到最后一个下载线程完成。计算正在执行下载的线程总数,如果既没有线程正在下载,又没有未完成的下载项目,那么表示任务完成,遍历这10个线程,向这是个线程发送退出消息。这样所有线程都会退出了,任务完成