如题1:线程代码constructor TClientPrintThread.Create(var Grid: TtsGrid; Suspended:Boolean);
begin
  inherited Create(Suspended);
  FSendData:=TSendData.create; //是个发送数据的对象,封装了发送数据函数
  SGrid:=Grid
  FreeOnTerminate   := false;  //线程执行完,不释放end;
destructor TClientPrintThread.Destroy;
begin
  inherited;
end;procedure TClientPrintThread.Execute;
begin
 while not Terminated do
   begin
     try
       //开始发送数据
       FSendData.SendText;
     finally
     end;
     Suspend;
  end;
end;//线程创建7个
for i:=1 to 7
  begin
    FClientPrintThread[i]:=TClientPrintThread.create(Grid[i],true) //线程创建后挂起
    FClientPrintThread[i].resume; //启动多线程
  end;
//然后调用对象 执行循环发送Procedure FSendData.SendText;
var
 I:integer;
begin
  for i:=1 to do 10000 then
     begin 
       application.ProcessMessages;
       //向com口发送数据 代码忽略
     end;end;//问题:7个多线程里 有1~2个多线程一段时间后会没有反应,停止向端口发送数据了,多线程也无法访问,执行挂起或者唤醒时提示 错误 “拒绝访问”来者有分!!!!

解决方案 »

  1.   

    关于线程的:http://blog.csdn.net/Oracle10g/archive/2006/10/24/1349277.aspx
      

  2.   

    hehe 给你顶了 问题不懂 等高人吧
      

  3.   

    如果向多个Com端口发送数据,应该不会有问题(现在的Com速率至少在115.2k以上),
    但,楼主的代码是指向一个COM口,7次并发操作,可能造成COM缓冲池涨满而阻塞,形成线程被动挂起,停止响应.
      

  4.   

    还有,如果长时间等待线程又"活"过来了,极有可能造成com口的输出数据丢失.
      

  5.   

    楼上说的有道理,另外你的
    FreeOnTerminate   := false;  //线程执行完,不释放 
    不知你这句意思是什么,为什么不释放
    另外在
    Procedure FSendData.SendText; 
    var 
     I:integer; 
    begin 
      for i:=1 to do 10000 then 
         begin  
           application.ProcessMessages; 
           //向com口发送数据 代码忽略 
         end; 
    里加上try语句,更好一点,因为由于硬件的原因,难保在执行时不出现错误,例如楼上所说的,这样程序会更键壮
      

  6.   

    觉得你的代码有好几个地方不知道你为什么要这么写.
    1.Destroy方法你既然不做任何另外的操作为什么要去覆盖它.(不知道你这里是不是用了override关键字)而根据FSendData是在Create里创建的,那你应该是
       在这里做FSendData的Free操作,然后再inherited Destroy;
    2.SendText既然是在execute里的,而且也不是在Synchronize里用,那就是说它只要不要使用到界面上的组件,
      application.ProcessMessages;这句代码就最好删掉,如果有用到界面上的组件,那你就该把这个操作放到
      Synchronize里去做,而不该在这里使用application.ProcessMessages否则就失去了效率.
    3.for i:=1 to do 10000 then 这里好象语法错了吧.既然while not Terminated do了再加for到10000的循环,怎么看怎么别扭.
      

  7.   

    上面的代码 只是临时 写的一个,系统代码比较乱,多线程 创建后 一直让他循环 作一件事情,做完一件事情挂起,如果下一个事情来了 执行Resume 继续执行
    此程序 是多个线程 向多个Com口发送数据,每次可能循环发送几万次才能结束,
      

  8.   

    这里:
    Procedure FSendData.SendText;
    是否应该有Com口号码参数?否则,如果采用应用程序轮询方式判断端口是否空闲,再作标记,不允许别人访问,最后释放标记,好像不太合理.很容易造成死锁.
      

  9.   

    每一个多线程 指定一个COM口 目前只模拟向端口发送 启动7个线程 时间一长偶尔会有1~2个线程没有反映了
      

  10.   

    感觉还是COM的处理能力问题.试试:
    Procedure FSendData.SendText;  
    var  
     I:integer;  
    begin  
      for i:=1 to do 10000 then  
         begin   
           //application.ProcessMessages;  不推荐使用此过程
           Sleep(10);                      //建议强制让Com休息一下,嘻嘻
           //向com口发送数据 代码忽略  
         end;  
      

  11.   

    1.线程执行完了不让端口休息,强占?
    2.楼主也许曲解了多线程.
    3.给你一个例子,不知是否对你有所启发,代码以下:{前题是例子的线程是建立在窗体单元中,用临界给线程空间}
    procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
    begin
      deletecriticalsection(cs);//清除临界区
    end;procedure TForm1.FormCreate(Sender: TObject);
    begin
      initializecriticalsection(cs); //创建临界区
    end;{---------------线程的声明---------------}
    ThztopyThread=class(TThread)
      private
        FAdoTable:TADOTable;
        FForm:TForm1;
        Fco:^boolean;
        Fs,Fe:integer;
      protected
        procedure Execute;override;
      public
        constructor Create(AdoTable:TADOTable;Form:TForm1;s:integer;e:integer;var co:boolean);
        destructor Destroy;override;
      end;
    var
      Form1: TForm1;
      threadrunning:integer;{--启动了的线程个数--}
      co:boolean;
      t1,t2,t3,t4,t5,t6,t7:ThztopyThread;{--------7个线程变量--------------}
      cs:trtlcriticalsection; //线程临界区变量
    implementation
    destructor ThztopyThread.Destroy;
    begin
      FAdoTable.Active:=false;
      FAdoTable.Free;
      inherited Destroy;end;constructor ThztopyThread.Create(AdoTable:TADOTable;Form:TForm1;s:integer;e:integer;var co:boolean);
    begin
      {---代码略----}
      inherited Create(False);
    end;procedure ThztopyThread.Execute ;
    begin
      freeonterminate:=true;
      entercriticalsection(cs);  //------------进入临界区
      {--执行的代码略--}
    end;
    procedure TForm1.We_ani(sender:tobject);{线程执行完毕所调用的过程}
    begin
       threadrunning:=threadrunning-1;{线程个数减一}
       if threadrunning<=0 then begin 
       messagebox(Handle,'全部线程执行完毕','提示',MB_ICONINFORMATION);
       end;
       leavecriticalsection(cs); {离开临界区}
    end;
    procedure TForm1.Button1Click(Sender: TObject);
    begin
         threadrunning:=7;     t1:=ThztopyThread.Create(ADOTable1,Form1,0,l1,co);
         t1.OnTerminate:= We_ani;     t2:=ThztopyThread.Create(ADOTable1,Form1,l1,l2+l1,co);
         t2.OnTerminate:= We_ani;     t3:=ThztopyThread.Create(ADOTable1,Form1,l1+l2,l1+l2+l3,co);
         t3.OnTerminate:= We_ani;     t4:=ThztopyThread.Create(ADOTable1,Form1,l1+l2+l3,l1+l2+l3+l4,co);
         t4.OnTerminate:= We_ani;     t5:=ThztopyThread.Create(ADOTable1,Form1,l1+l2+l3+l4,l1+l2+l3+l4+l5,co);
         t5.OnTerminate:= We_ani;     t6:=ThztopyThread.Create(ADOTable1,Form1,l1+l2+l3+l4+l5,l1+l2+l3+l4+l5+l6,co);
         t6.OnTerminate:= We_ani;     t7:=ThztopyThread.Create(ADOTable1,Form1,l1+l2+l3+l4+l5+l6,l7,co);
         t7.OnTerminate:= We_ani;
    end;
    以上每个线程创建时都进入一个临界区,当执行完了就会离开临界区,以此可给每个线程有执行空间.
      

  12.   

    死锁,在FSendData.SendText;方法中加入临界区
      

  13.   

    constructor TClientPrintThread.Create(var Grid: TtsGrid; Suspended:Boolean); 
    begin 
      inherited Create(Suspended); 
      FSendData:=TSendData.create; //是个发送数据的对象,封装了发送数据函数 
      SGrid:=Grid 
      FreeOnTerminate   := false;  //线程执行完,不释放 end; 
    destructor TClientPrintThread.Destroy; 
    begin 
      inherited; 
    end; procedure TClientPrintThread.Execute; 
    begin 
     while not Terminated do 
       begin 
         try 
           //开始发送数据 
           FSendData.SendText; 
          
         finally 
         end; 
         //Suspend; 
      end; 
    end; //线程创建7个 
    for i:=1 to 7 
      begin 
        FClientPrintThread[i]:=TClientPrintThread.create(Grid[i],true) //线程创建后挂起 
        FClientPrintThread[i].resume; //启动多线程 
      end; 
    //然后调用对象 执行循环发送 Procedure FSendData.SendText; 
    var 
     I:integer; 
    begin 
      for i:=1 to do 10000 then 
         begin  
           //application.ProcessMessages; --->
           Sleep(10); 
           //向com口发送数据 代码忽略 
         end; end; 
      

  14.   

    加上Sleep,有可能就是这个原因
      

  15.   

    我觉得楼主有必要仔细的看看TThread类的封装,TThread里的某些代码是不在子线程中执行的,而是在主线程里.
    还有要指出的是,你的这种循环暂停,resume的模式一定是有问题的.你不妨用完成端口,或者用同步事件,信号量等来处理这个问题.
    在没有信号的时候让线程等待(WaitforSingleobject,而不是用sleep)直到读取到数据后发送消息等方法来实现.
      

  16.   

    學習for i:=1 to 7 
      begin 
        FClientPrintThread[i]:=TClientPrintThread.create(Grid[i],true) //线程创建后挂起 
        FClientPrintThread[i].resume; //启动多线程 
      end; 這段代碼,樓主有沒有時過用try finally end
    看能執行幾個線程