(█(█(█(█在线程中用了while,陷入死循环,其他任务不能同步处理--然后加入Application.ProcessMessages,所有任务都同步处理了

  • 主题发起人 主题发起人 NetNoCenter
  • 开始时间 开始时间
N

NetNoCenter

Unregistered / Unconfirmed
GUEST, unregistred user!
(█(█(█(█在线程中用了while,陷入死循环,其他任务不能同步处理--然后加入Application.ProcessMessages,所有任务都同步处理了,但CPU全部被占用---然后加入sleep(1),CPU降了下来--然后.....问题来了 (41分)<br />{这个while循环是放在线程程里的}
也就是:
TMyThread.Execute;
begin
while ... do
begin
//任务处理
end;
end;
//陷入死循环,其他任务不能同步处理
然后改为
TMyThread.Execute;
begin
while ... do
begin
//任务处理
Application.ProcessMessages;
end;
end;
//所有任务都同步处理了,但CPU全部被占用
然后改为
TMyThread.Execute;
begin
while ... do
begin
//任务处理
sleep(1);
Application.ProcessMessages;
end;
end;
//CPU降了下来
这里我想问一下各位大侠
1 用 sleep(1);是不是在不同机器上有可能引起程序不稳定?为什么?
2 用 sleep(1);效率会降低?因为有延迟,
3 在这类需要循环的应用中,假如不用sleep(1)来降CPU,那有什么比较好的办法?
1) 听说用MsgWaitForMultipleObjects可以达到比较好的效果,但我不会用这东西,各位大侠具体给点详细提示,看了MIDAS中的ScktSrvr里的一段,可是还是看的不明白:
procedure TSocketDispatcherThread.ClientExecute;
var
Data: IDataBlock;
msg: TMsg;
Obj: ISendDataBlock;
Event: THandle;
WaitTime: DWord;
begin
CoInitialize(nil);
try
Synchronize(AddClient);
FTransport := CreateServerTransport;
try
Event := FTransport.GetWaitEvent;
PeekMessage(msg, 0, WM_USER, WM_USER, PM_NOREMOVE);
GetInterface(ISendDataBlock, Obj);
if FRegisteredOnly then
FInterpreter := TDataBlockInterpreter.Create(Obj, SSockets) else
FInterpreter := TDataBlockInterpreter.Create(Obj, '');
try
Obj := nil;
if FTimeout = 0 then
WaitTime := INFINITE else
WaitTime := 60000;
while not Terminated and FTransport.Connected do
try
case MsgWaitForMultipleObjects(1, Event, False, WaitTime, QS_ALLEVENTS) of
WAIT_OBJECT_0:
begin
WSAResetEvent(Event);
Data := FTransport.Receive(False, 0);
if Assigned(Data) then
begin
FLastActivity := Now;
FInterpreter.InterpretData(Data);
Data := nil;
FLastActivity := Now;
end;
end;
WAIT_OBJECT_0 + 1:
while PeekMessage(msg, 0, 0, 0, PM_REMOVE) do
DispatchMessage(msg);
WAIT_TIMEOUT:
if (FTimeout &gt; 0) and ((Now - FLastActivity) &gt; FTimeout) then
FTransport.Connected := False;
end;
except
FTransport.Connected := False;
end;
finally
FInterpreter.Free;
FInterpreter := nil;
end;
finally
FTransport := nil;
end;
finally
CoUninitialize;
Synchronize(RemoveClient);
end;
end;
有对MsgWaitForMultipleObjects非常了解的大侠支一下招(参数详细讲解一下?),假如我有消息到达了,我通过自己定义消息wm_usermsg来通知有消息到达,那我该怎么发送这个消息(用SENDMESSAGE?),让MsgWaitForMultipleObjects能够捕获到?
这里有个EVENT,不知道什么意思,假如要在我自己的应用中应用,我该怎么定义EVENT?

2)假如不用上面这个方法,还有什么更好的方法?
 
这个那就你要去看DELPHI的相关的内核了,我觉得DELPHI的内存分配机制有点差,占CPU太多,内存呢有时又不要,搞得很烦人,远不如C++的干净
 
TMyThread.Execute;
begin
while ... do
begin
//任务处理
sleep(1);
// 不能使用,除非用同步调用一个线程的过程 Application.ProcessMessages;
end;
end;
//CPU降了下来
这里我想问一下各位大侠
1 用 sleep(1);是不是在不同机器上有可能引起程序不稳定?为什么?
不会引起不稳定!
2 用 sleep(1);效率会降低?因为有延迟,
不会降低效率,因为1ms在线程处理中是微不足道的!
3 在这类需要循环的应用中,假如不用sleep(1)来降CPU,那有什么比较好的办法?
就用Sleep了!我的程序也在用喔,嘿嘿!
 
TO wql:
为什么不能用Application.ProcessMessages;?
假如不用Application.ProcessMessages;,在我程序里其他线程就不能正常工作了(比如及时更新界面的显示什么的)
 
可以用临界区来同步界面的更新。
 
sleep(1)是很多程序,包括一些游戏都采用的技术,没什么。
 
Application.HandleMessage
 
把你的这个工作线程的优先级降低一些,主线程就有更多的机会处理消息了。

如果你要同步若干个线程,还是要使用线程同步对象的;互斥可以用临界区。
 
MsgWaitForMultipleObjects可以使用自定义消息 ,当你需要线程执行相关操作时,可使用
PostthreadMessage(threadID, WM_USER+1, 0 ,0)
在while PeekMessage(msg, 0, 0, 0, PM_REMOVE) do 判断,如
IF Msg.message = WMUSER+1 then
Begin
执行相关操作
end
ELSE
DispatchMessage(msg);
 
后退
顶部