问题是:
    我现在程序用到了4个线程,在线程execute里使用了死循环
    while not terminated do 
    begin
    
    end;   
    thread_disp_one, thread_disp_two, thread_disp_three, thread_disp_four : TDisp_thread; 4个线程,执行体相同;
    
    在关闭程序时,我不知道怎么写能够正常关闭线程,使正在死循环的线程终止而正常关闭程序.

解决方案 »

  1.   

    把你所有的代码贴出来,你循环的时候是不是用到了什么公共的信息如果只是简单的结束线程,按照你这种写法,直接调用TThread的Terminate方法就可以,它会把FTerminated 置为true,你的线程就会结束,但资源没有释放,可以在你进入死循环的代码前边加上FreeOnTerminate := true;procedure TThread.Terminate;
    begin
      FTerminated := True;
    end;
      

  2.   

    constructor TDisp_thread.create(com_para_no : integer; ado_conn_no, disp_no: string);
    begin
         inherited Create(True);
         FreeOnTerminate := True;
         ds := TSendToLedOCX.Create(nil);
         thread_ado_conn_no := ado_conn_no;
         thread_disp_str := disp_str;
         thread_delay_time := delay_time;
         fScreenNostr := disp_no;
         fColor := 2;
         fFontLibNo := 255;     
         try
            ds.SetComm(0, com_para_no, disp_baud, '0');
         except
            Synchronize(thread_setup);
            Terminate;
         end;
         synchronize(ClearScr);
         sleep(1000);
         synchronize(DispSleepStr);
         sleep(1000);
         Resume;
    end;procedure TDisp_thread.Execute;
    var
         i : integer;
         q_del : tmysql;
    begin
         while not terminated do
         begin
              CoInitialize(nil);
              
              IsCheckRateDisp;
              SetDispStr();
              if IDCount > 0 then
              begin
                    if count = 0 then
                    begin
                         synchronize(NoRecord);
                         sleep(strtoint(thread_delay_time));
                         synchronize(DispSleepStr);
                         sleep(1000);
                    end
                    else
                    begin
                         for i := 0 to int_count - 1 do
                         begin
                              SetCount(i);
                              synchronize(MoreRecord);
                              sleep(strtoint(thread_delay_time));
                         end;                     if mod_count = 0 then
                         begin
                               q_del := tmysql.Create(strtoint(thread_ado_conn_no));
                               q_del.sql_str('delete from DisPlayDealInfo where DS_ID = '''+dsid+''' ', false);
                               q_del.DestroySelf;                           synchronize(Record_zero);
                               sleep(strtoint(thread_delay_time));
                               synchronize(DispSleepStr);
                               sleep(1000);
                         end;                     if mod_count = 1 then
                         begin
                               q_del := tmysql.Create(strtoint(thread_ado_conn_no));
                               q_del.sql_str('delete from DisPlayDealInfo where DS_ID = '''+dsid+''' ', false);
                               q_del.DestroySelf;                           synchronize(Record_one);
                               sleep(strtoint(thread_delay_time));
                               synchronize(DispSleepStr);
                               sleep(1000);
                         end;                     if mod_count = 2 then
                         begin
                               q_del := tmysql.Create(strtoint(thread_ado_conn_no));
                               q_del.sql_str('delete from DisPlayDealInfo where DS_ID = '''+dsid+''' ', false);
                               q_del.DestroySelf;                           synchronize(Record_one);
                               sleep(strtoint(thread_delay_time));
                               synchronize(DispSleepStr);
                               sleep(1000);
                         end;                     if mod_count = 3 then
                         begin
                               q_del := tmysql.Create(strtoint(thread_ado_conn_no));
                               q_del.sql_str('delete from DisPlayDealInfo where DS_ID = '''+dsid+''' ', false);
                               q_del.DestroySelf;                           synchronize(Record_one);
                               sleep(strtoint(thread_delay_time));
                               synchronize(DispSleepStr);
                               sleep(1000);
                         end;                     if mod_count = 4 then
                         begin
                               q_del := tmysql.Create(strtoint(thread_ado_conn_no));
                               q_del.sql_str('delete from DisPlayDealInfo where DS_ID = '''+dsid+''' ', false);
                               q_del.DestroySelf;                           synchronize(Record_one);
                               sleep(strtoint(thread_delay_time));
                               synchronize(DispSleepStr);
                               sleep(1000);
                         end;                     if mod_count = 5 then
                         begin
                               q_del := tmysql.Create(strtoint(thread_ado_conn_no));
                               q_del.sql_str('delete from DisPlayDealInfo where DS_ID = '''+dsid+''' ', false);
                               q_del.DestroySelf;                           synchronize(Record_one);
                               sleep(strtoint(thread_delay_time));
                               synchronize(Add_five);
                               sleep(strtoint(thread_delay_time));
                               synchronize(DispSleepStr);
                               sleep(1000);
                         end;                     if mod_count = 6 then
                         begin
                               q_del := tmysql.Create(strtoint(thread_ado_conn_no));
                               q_del.sql_str('delete from DisPlayDealInfo where DS_ID = '''+dsid+''' ', false);
                               q_del.DestroySelf;                           synchronize(Record_one);
                               sleep(strtoint(thread_delay_time));
                               synchronize(Add_six);
                               sleep(strtoint(thread_delay_time));                           
                               synchronize(DispSleepStr);
                               sleep(1000);
                         end;                     if mod_count = 7 then
                         begin
                               q_del := tmysql.Create(strtoint(thread_ado_conn_no));
                               q_del.sql_str('delete from DisPlayDealInfo where DS_ID = '''+dsid+''' ', false);
                               q_del.DestroySelf;                           synchronize(Record_one);
                               sleep(strtoint(thread_delay_time));
                               synchronize(Add_seven);
                               sleep(strtoint(thread_delay_time));
                               synchronize(DispSleepStr);
                               sleep(1000);
                         end;                     if mod_count = 8 then
                         begin
                               q_del := tmysql.Create(strtoint(thread_ado_conn_no));
                               q_del.sql_str('delete from DisPlayDealInfo where DS_ID = '''+dsid+''' ', false);
                               q_del.DestroySelf;                           synchronize(Record_one);
                               sleep(strtoint(thread_delay_time));
                               synchronize(Add_eight);
                               sleep(strtoint(thread_delay_time));
                               synchronize(DispSleepStr);
                               sleep(1000);
                         end;                     if mod_count = 9 then
                         begin
                               q_del := tmysql.Create(strtoint(thread_ado_conn_no));
                               q_del.sql_str('delete from DisPlayDealInfo where DS_ID = '''+dsid+''' ', false);
                               q_del.DestroySelf;                           synchronize(Record_one);
                               sleep(strtoint(thread_delay_time));
                               synchronize(Add_nine);
                               sleep(strtoint(thread_delay_time));
                               synchronize(DispSleepStr);
                               sleep(1000);
                         end;                                                                                                    end;
              end;                CoUnInitialize();
         end;
    end;
      

  3.   

    代码太长,没有仔细看,不过给你提几个建议
    1、如果有可能,把   inherited Create(True);放到改成   inherited Create(false)放到最后,减少系统开销
    2、循环体内不要每次都 CoInitialize(nil);
    3、你的条件判断最好用case,可以减少一些系统开销
    4、你上面代码中的用来对数据库操作的地方这样用在多线程中貌似有问题,最好加上同步的代码,不要每次都 tmysql.Create。
    5、你的sleep(1000)意义不大。关于你的问题,只有你自己调试解决,因为只有你了解自己的代码流程,好好分析一下,看看都用到了什么资源,然后根据线程调度情况来分析你的问题,你的问题可能就是多个资源释放的问题,最好你先了解一下win32下的线程究竟是怎么回事,看看TThread对象是如何封装线程操作的。如果只是简单的结束线程,那么可以用下面的办法:若要终止线程的运行,可以使用下面的方法:
    • 线程函数返回(最好使用这种方法)。
    • 通过调用ExitThread函数,线程将自行撤消(最好不要使用这种方法)。
    • 同一个进程或另一个进程中的线程调用TerminateThread函数(应该避免使用这种方法)。
    • 包含线程的进程终止运行(应该避免使用这种方法)。