关于多线程占用CPU资源的问题!(难!)(100分)

  • 主题发起人 主题发起人 黑狼
  • 开始时间 开始时间

黑狼

Unregistered / Unconfirmed
GUEST, unregistred user!
简单代码如下:
procedure tsendthread.execute;
begin
while not terminateddo
begin
if sign=true then
begin
//some code;
end;
end;

end;
sign为判断是否发送数据的标志位!问题出现在sign大部分时间是为false,所以此线程
就如同一个死循环一直在检查sign。
而且我写的程序页面控件比较多切换时页面时响应速度特别慢,我曾经试过降低此线程的
优先级,但是效果还是不好,而我创建这个线程的想法是此线程可以实时监控数据。
虽然,我用timesetevent可以解决这问题,但是我写的程序比较大了,改动起来特别费劲,
所以我想请各位高手帮我解决这个问题,用多线程的方法来解决,多谢了!
 
procedure tsendthread.execute;
begin
while not terminateddo
begin
if sign=true then
begin
//some code;
end;
sleep(50);
//attention here.
end;

end;
 
我试过了,不过效果也不好。如下:
application.progressmessages;
sleep(50);
 
你用的是线程,不需要application.progressmessages
 
是的,但是如果程序只执行
while not terminateddo
if sign=true then
这两行时不也如同死循环吗?你可以试一试。连程序的关闭按钮也会无效的。
 
不要用变量来 实现同步,换用 信号量
 
是用waitforsingleobject吗?怎么用,能给出具体代码吗?
 
用sleep()是可以的,时间稍微长一些,效果会好点
用 WaitForSingleobject也可以
var
hMutex:THandle=0;//
hMutex:=CreateEvent(nil,false,false,nil);
//信号源
在线程中
While not Terminateddo
begin
//while
WaitForSingleobject(hmutex,infinite);
//其它代码
end;

还需要一个timer定时发信号
setEvent(hMutex);//
 
可以用互斥对象实现线程同步。
先在主线程中创建事件对象:
var
hMutex: THandle = 0;
...
hMutex := CreateMutex(nil, False, nil);
在线程的Execute方法中加入以下代码:
if WaitForSingleObject(hMutex, INFINITE) = WAIT_OBJECT_0 then
//Do Something;
...
ReleaseMutex(hMutex);
最后记得要释放互斥对象:
CloseHandle(hMutex);

 
但是,我对信号量和互斥对象不怎么明白。
信号量是不是当一个对象被一个线程拥有时,它处于不发信号状态,相反则是发信号状态。
WaitForSingleobject(hmutex,infinite);
这一步它是怎么工作的,因为WaitForSingleobject只有三个返回值wait_object_0,
wait_timeout,另一个我忘了。
能给出一个具体的源代码吗?
 
用Sleep把线程挂起一段时间,让OS把CPU时间分配给其它进程或线程
 
循环中加一句即可:
Sleep(0);
 
推荐用TEVENT事件,用WaitForSingleobject等待,不需要进行大花消的循环
 
我觉得尽量不要在线程用sleep,要用MsgWaitForMultipleObjects,
在线程外用SetEvent来做终止等待的一些处理。
 
当一个互斥对象不再被一个线程所拥有,它就处于发信号状态。此时首先
调用WaitForSingleObject()函数的线程就成为该互斥对象的拥有者,此互斥
对象设为不发信号状态。当线程调用ReleaseMutex()函数并传递一个互斥对象
的句柄作为参数时,这种拥有关系就被解除,互斥对象重新进入发信号状态。
WaitForSingleObject函数的返值:
WAIT_ABANDONED指定的对象是互斥对象,并且拥有这个互斥对象的线程在
没有释放此对象之前就已终止。此时就称互斥对象被抛弃。这种情况下,这个
互斥对象归当前线程所有,并把它设为非发信号状态;
WAIT_OBJECT_0 指定的对象处于发信号状态;
WAIT_TIMEOUT等待的时间已过,对象仍然是非发信号状态;
具体的源代码可以参考《Delphi 5开发人员指南》。
到处有下载,用Google搜索一下。
 
首先要确定你的任务是否一定需要线程来完成,若一定要线程来完成,在线程中不断进行循环
来检测一个变量不是一个好办法,上面的不少同志已经提供了不少思路,我这里提供另外一些思路:
可以在线程里面建立一个消息循环,在调用线程的地方通过postThreadMessage来进行触发就可以。
 
程序我改完了,使用信号量的方法改的效果不错!^_^所以我决定把分数分给提出信号量
方法的兄弟们。
 
后退
顶部