关于线程的奇怪问题(100分)

  • 主题发起人 主题发起人 screen
  • 开始时间 开始时间
S

screen

Unregistered / Unconfirmed
GUEST, unregistred user!
我写了一个线程,轮询一个链表,处理链表中的节点,处理完后,就删除链表中的该节点,
当处理完所有节点后,就把自己挂起。另外的一个地方向链表中加入节点。加入后,调用
myThread.resume来激活已经挂起的线程。按道理是很简单的咚咚,可是在实际应用中发现有时候该线程调用resume后,还是没有被激活,于是我就用:
while mythread.suspendeddo
myThread.resume.
效果好了一些,但还是有时候出现不能再次被激活的情况,不知道科学的写法应该是怎样的?请高手指教。
不用考虑链表保护等弱智问题。
 
这么巧,我也碰到这个问题,同样,我也是写一循环链表!
问题在这里.
你的处理完节点以后写
YourThread.Suspended;
这个过程马上就返回了,!!!!!!!!
然后这个线程就执行完毕,就Terminate了,当然,你再Resume就不行了.
解决办法一
不调用Resume,调用Execute,不过有局限,因为Execute就protected方法,
你无法再别的单元调用,除非你的线程类在你要调用的单元.
标准解决办法:
while not Terminateddo
begin
if ok then
Suppend;
//处理完成以后就挂起
end;

需要中止线程时就YourThread.Terminated:=True就OK了!
 
我也是用这个while 死循环来处理的啊,suspend并没有退出线程的execute。
只是挂起了而已。
你没有遇到类似问题么?
 
补充一句,我的While 循环是在线程的Execute里的:
procedure MyThread.Execute;
begin
while not Teriminateddo
begin
//do something
if ok then
Supspend;
end;
在这里Terminated是TThread的成员变量,
你自己尝试调试一下,在Resume以前,看看线程的状态,是不是挂起,还是Terminated:=True
我想是没有问题!
 
我的也是耶,在execute里面,
这个问题很奇怪,大部分地方都不出,因为这个程序已经在很多地方用了,都没有这个问题,我怀疑是不是和机子速度有关系哦?或者和机子配置有关系?
我把代码贴出来大家看看嘛
procedure myThread.Execute;
begin
while (not Terminated)do
//系统没有关闭
begin
while(UnitList.Count <> 0)do
begin
if Terminated then
begin
Break;
end;
//取一个节点
WaitForSingleObject(AMutex,INFINITE);//加锁
Temp := UnitList.Items[0];
UnitList.Delete(0);
ReleaseMutex(AMutex);
//开锁
//对这个节点进行处理
if Temp = nil then
Continue;
do
It(Temp);
Dispose(Temp);
//释放该节点
end;
//end of while
if Terminated then
Break;
Suspended := true;
//刮起
end;
//end of while
end;

procedure WM_Report(var rp_msg:Tmessage);
Message WM_FMRP;
procedure Twin.WM_Report(var rp_msg:Tmessage);
begin
while myThread.Suspendeddo
myThread.Resume ;
end;

另外的地方就是加入链表,然后postMessage(WM_FMRP)消息通知激发该线程。
 
应该是没有什么问题!
不过顺便提几点,你的编码习惯不是很好比如while (not Terminated)do
中的括号
是不需要的,也是Borland不提倡的,另外你的很多Break语句没有什么有
 
这有什么奇怪的,你调用resume时也许线程还没运行到suspend语句呢,也就是说那时线程还活跃的,这句resume等于一句空语句。等线程真正运行到suspend后已经没有人再去resume它了。
关键问题是链表的轮询代码。你必须保证链表节点已经空了才能suspend而不能简单一次循环就suspend了。所以最关键的地方反而正是你说的弱智的链表保护。
至于第二个线程只要简单用if mythread.suspended then
mythread.resume就可以了,因为你可以肯定mythread 没有suspended时它还会继续处理你刚添加进取的节点,而不会suspend。
 
帮你向前一些!
 
可能是PostMessage发的消息未被处理,我曾经遇到在线程内PostMessage后主线程的消息处理函数捕获不到消息的情况,奇怪的是这种现象只在Win98上出现,到了Win2000/XP下就一切正常了。
 
同意Another_eYes:
还有,你线程的FreeOnTerminate是不是设成True了。
如果设成True,terminate后就直接Destroy了。
 
以前我也碰到过此问题,其实不用用suspend挂起Thread, 只要用sleep(10);来代替即可。
例 :
while not terminateddo
begin
if not myQueue.IsEmptydo
begin
myQueue.Pop(aNode);
//处理aNode;
sleep(10);
end
sleep(10);
end;
 
Another_eYes:
我是等链表为空了才SUSPEND 阿,
我现在唯一怀疑的地方是判断 UnitList.Count <> 0这句是否应该保护起来,
 
后退
顶部