如何让等待的线程让出cpu

时间:2021-02-17 21:43:46
procedure TMyThread.Execute;
begin
  inherited;
  while(not terminated) do begin
    try
    Application.ProcessMessages;
   synchronize(invoke);
    sleep(100);
    except on E:Exception do
        showMessage(E.Message);
    end;
  end;
end;

procedure TMyThread.invoke;
var
  buf:array[0..1024] of char;
begin
  with form1 do begin
     TcpClient1.ReceiveBuf(buf,1000,0);
    if buf<>'' then begin
      StringGrid1.Rows[StringGrid1.RowCount-1].Add(IntToStr(count+1));
      StringGrid1.Rows[StringGrid1.RowCount-1].Add(DateTimeToStr(Now()));
      StringGrid1.Rows[StringGrid1.RowCount-1].Add(buf);
      StringGrid1.RowCount:=StringGrid1.RowCount+1;
      inc(count);
      label6.Caption:='Now receive '+IntToStr(count)+' pieces of message!';
    end;
  end;
end;
我要从服务器端不断的接收信息来, 但是当没有信息从server端出来时, 整个程序就像死了一样,不再响应任何操作,如果把  synchronize(invoke)  中的"synchronize" 去掉的话就没有这种情况, 可是这样一来,每当关闭该程序时又会出现一个异常,可能是因为线程里操作了vcl控件的原因故而加上synchronize 在关闭时就没有问题了.  我现在的问题是: 当server端没有信息发出来时如何让 线程让出 CPU来以便可以响应程序的其它操作.

望各位大侠不吝赐教, 小弟不胜感激.  如果愿意的话请留QQ,或是MSN,本人的QQ:342853167,Msn:dengy1979@hotmail.com

6 个解决方案

#1


Sleep(0);

#2


Application.ProcessMessages;
這句有問題, 要去掉! 

如你這種情況, 你應該在線程中用 PostMessage 向主線程發送一條接收到數據結核的消息,
然後, 讓主線程去處理顯示的問題, 而不是在線程中操作 UI 界面!

synchronize 在這裹作用不明顯, 我估計去掉也不會去錯才對!


#3


信号量

#4


你的这个线程没有太大的意义,没有数据的时候线程也在无效的循环
而且还用synchronize这个函数,这个还是就是把操作控件的代码放到主线程中的
所以你还不如在主线程的接受事件里写代码呢.


    Application.ProcessMessages;
   synchronize(invoke);
    sleep(100);
这三句话都回使线程挂起在恢复,效率很低,尤其是synchronize这个函数附带的操作很多.

你的线程关闭出现异常可这这样看看
   MyThread.Terminate;
   MyThread.Waitfor;

解决问题比较好的方法是用线程同步和WaitForMultipleObjects函数才能高效运行.
或者平常把线程挂起,在接受事件触发时唤起线程

   

#5


同上,mark.

#6


你知道线程什么意思吗?
知道synchronize是干什么的吗?

var
  buf:array[0..1024] of char; //TMyThread的私有变量

procedure TMyThread.Execute;
begin
  while(not terminated) do begin
    try
      TcpClient1.ReceiveBuf(buf,1000,0);//TcpClient1在线程里创建最好,如果不,传进来也行
      if buf<>'' then begin
        synchronize(invoke);
      TcpClient1.WaitForData();
    except on E:Exception do
        //showMessage(E.Message);不要这样吗,有异常可以写日志,真弹窗口麻烦就大了
    end;
  end;
end;

procedure TMyThread.invoke;
begin
  with form1 do begin
      StringGrid1.Rows[StringGrid1.RowCount-1].Add(IntToStr(count+1));
      StringGrid1.Rows[StringGrid1.RowCount-1].Add(DateTimeToStr(Now()));
      StringGrid1.Rows[StringGrid1.RowCount-1].Add(buf);
      StringGrid1.RowCount:=StringGrid1.RowCount+1;
      inc(count);
      label6.Caption:='Now receive '+IntToStr(count)+' pieces of message!';
  end;
end;

#1


Sleep(0);

#2


Application.ProcessMessages;
這句有問題, 要去掉! 

如你這種情況, 你應該在線程中用 PostMessage 向主線程發送一條接收到數據結核的消息,
然後, 讓主線程去處理顯示的問題, 而不是在線程中操作 UI 界面!

synchronize 在這裹作用不明顯, 我估計去掉也不會去錯才對!


#3


信号量

#4


你的这个线程没有太大的意义,没有数据的时候线程也在无效的循环
而且还用synchronize这个函数,这个还是就是把操作控件的代码放到主线程中的
所以你还不如在主线程的接受事件里写代码呢.


    Application.ProcessMessages;
   synchronize(invoke);
    sleep(100);
这三句话都回使线程挂起在恢复,效率很低,尤其是synchronize这个函数附带的操作很多.

你的线程关闭出现异常可这这样看看
   MyThread.Terminate;
   MyThread.Waitfor;

解决问题比较好的方法是用线程同步和WaitForMultipleObjects函数才能高效运行.
或者平常把线程挂起,在接受事件触发时唤起线程

   

#5


同上,mark.

#6


你知道线程什么意思吗?
知道synchronize是干什么的吗?

var
  buf:array[0..1024] of char; //TMyThread的私有变量

procedure TMyThread.Execute;
begin
  while(not terminated) do begin
    try
      TcpClient1.ReceiveBuf(buf,1000,0);//TcpClient1在线程里创建最好,如果不,传进来也行
      if buf<>'' then begin
        synchronize(invoke);
      TcpClient1.WaitForData();
    except on E:Exception do
        //showMessage(E.Message);不要这样吗,有异常可以写日志,真弹窗口麻烦就大了
    end;
  end;
end;

procedure TMyThread.invoke;
begin
  with form1 do begin
      StringGrid1.Rows[StringGrid1.RowCount-1].Add(IntToStr(count+1));
      StringGrid1.Rows[StringGrid1.RowCount-1].Add(DateTimeToStr(Now()));
      StringGrid1.Rows[StringGrid1.RowCount-1].Add(buf);
      StringGrid1.RowCount:=StringGrid1.RowCount+1;
      inc(count);
      label6.Caption:='Now receive '+IntToStr(count)+' pieces of message!';
  end;
end;