for i := 1 to 15 do
    begin
     repeat       with TshdThread.Create() do
         OnTerminate := ThreadDone;
       inc(ThreadRunning);     until threadRunning=maxthread;     //showmessage('aa');    end;

解决方案 »

  1.   

    上面高手的解法应该没问题!
    你的问题主要是由于满足条件后
    执行了死循环
    repeat
    until
    导致主线程进入死循环,以至于不能处理Windows消息
      

  2.   

    而且你访问ThreadRunning之前应该设定一个关键代码段,否则多个线程访问该变量会发生冲突的
      

  3.   

    procedure TOKBottomDlg.doit;
    var
      MaxThread : integer;
      i : integer;
    begin
      okbtn.Enabled := false;  ThreadRunning := 0;  //应是全局变量,在ThreadDone 中应将此值减1
      MaxThread := 4;
    //  ThreadFull := false;  for i := 1 to 15 do
      begin
         inc(ThreadRunning); 
         with TshdThread.Create() do
         begin
           OnTerminate := ThreadDone;
         end;     while threadRunning mod maxthread = 0 do  
             Application.ProcessMessages();  end;
      okbtn.Enabled := true;
    end;
      

  4.   

    补充,对全局变量ThreadRunning的读写要作同步处理,可用一个函对函数来作,读写都用临界区保护起来!
      

  5.   

    好!行者高手!我用了 
    while ThreadRunning=MaxThread do
        Application.ProcessMessages();解决了问题!380是你的了!由于一次只能给100分,所以请搜索你的名字,我用别的贴子来给你分。  别的同志也有!不过还请你指教,对ThreadRunning为什么要同步?如何同步?什么叫函对函数?临界区能否给个简单例子?
      

  6.   

    var  CS:TRTLCriticalSection;
    initialization
      InitializeCriticalSection(cs);
    finalization
      DeleteCriticalSection(cs);使用
         EnterCriticalSection(cs);LeaveCriticalSection(Cs);
      

  7.   

    这段代码是要你把对线程共享变量的读写访问放在
    EnterCriticalSection(cs);
      //访问共享变量
    LeaveCriticalSection(Cs);
    之间,这样就可以保证同步了!
      

  8.   

    呵呵,同意楼上,因为ThreadRunning是个全局变量,当多个线程同时读写它时可能出现与时间有关的错误, 所以,是好要同步,方法可用楼上的方法.建一个全局的CriticalSection对象,然后,在读和写ThreadRunning前用EnterCriticalSection; 读写之后用LeaveCriticalSection;
      

  9.   

    呵呵,还有所谓函对函数是我打错了,应是一对函数,即作一个函数用来读值,一个函数用来写值,在这一对函数里都要作同步
    定义全局变量g_CriticalSection := TCriticalSection.Create; 建立临界区(使用之前要建立,整个程序中只须建立一次)
    g_CriticalSection := TCriticalSection.Create;
    函数中读写前用
    g_CriticalSection.Enter;  //进入临界区函写后用
    g_CriticalSection.Leave;  //离开临界区
    最后要释放整个程序中只须释放一次
    if g_CriticalSection <> nil then FreeAndNil(g_CriticalSection);关于监界区,信号量,事件对象等内核对象的作用及使用方法,你可以参考相关的资料, 一般书上讲多线程的地方都会讲的,因为多线程一般是不可避免要用同步的.祝你进步!
      

  10.   

    呵呵,上面又错了,定义是用
    var
      g_CriticalSection : TCriticalSection;uses部分要加入 SyncObjs;
      

  11.   

    还是用信号元吧CreateSemaphore();,这样更安全hr: THandle;   ///信号元句柄procedure TOKBottomDlg.doit;
    var
      MaxThread : integer;
      i : integer;  
    begin
      okbtn.Enabled := false;  ThreadRunning := 0;
      MaxThread := 4;
      ThreadFull := false;  hr := CreateSemaphore(nil,MaxThread,MaxThread,nil);//建最多4个信号
      for i := 1 to 15 do
        begin
           WaitForSingleObject(hr,INFINITE);///减少一个
           showmessage('aa');
           with TshdThread.Create() do  OnTerminate := ThreadDone;
      
        end;
      okbtn.Enabled := true;
    end;procedure TOKBottomDlg.ThreadDone(Sender: TObject);
    begin
      label10.Caption := inttostr(RegSucc);
      Dec(ThreadRunning);
    end;你还要在线程TshdThread结束的地方加一句:
     ReleaseSemaphore(hr,1,nil);///增加一个