线程的怪问题(100分)

  • 主题发起人 hellotao
  • 开始时间
我的这个线程程序太奇怪了,
前两天还处理的好好的,
今天程序的前半段处理的好好的,到后半段,线程自己停了,
我换了好几种机制,比如Semaphore, CriticalSection 都不行,
今天有点烦,有点烦
 
我http://www.to-happy.com的《大事》软件卖了不少钱,
编程语言就是delphi。你能挑出软件的错吗?
 
if SleepTime > 0 then
Sleep(SleepTime);
如果你不在其他线程修改SleepTime的值的话不存在问题!否则的话他就可能是死锁的原因,存取它使用CriticalSection可以避免冲突。
问题出在:Synchronize(Step);
他会把Step交给主线城去完成,所以去跟踪一下Step的执行!这样的多线程时没有多大意义的,因为你把任务又交还给主线程了!线程导师几乎每做什么事!
 
to 无业游民
我把Synchronize 去掉以后就发现运行正常了,
为什么? 而且我的信号量也可以用了,
Synchronize 可能会导致些什么问题呢? 为什么会影响我的信号量,
导致线程的死锁呢?
 
你在什么地方使用了信号量?Synchronize会将过程交给主线程,然后线程等待主线程的执行完后返回!
你想想吧!看看那块出了问题!
 
好的, 能给我qq,
有问题象你请教?
我第一次用线程编程,
所以没有什么经验。
 
把那条语句注释掉再跟看看
 
你在哪里呢?
 
可能是你的代码产生了异常而你没有处理,DELPHI替你处理了,并中止了线程的执行!
这样试试:
while not Terminateddo
begin
try
...
except
end;
end;

 
我在上海,
 
我现在又有新问题了,
我的Step 方法中有和VCL界面组件打交道的代码,
这样会出现错误的,
 
把你的Step贴出来,给你找找问题!
作多线程系统要注意以下几个问题:
1、如果使用到VCL与界面交互(常见的就是显示消息、进度条等等),使用Synchronize
去执行这些过程,但是效率不会很高,而且这个过程不能太复杂!你也可以采用PostMessage
来让主线程异步完成一些工作,别用SendMessage哦,VCL是非线程安全的回死锁的。
2、使用VCL对象(不与界面交互)或使用全局对象等等(包括Thread的属性),请使用
临界区、信号量、或多重读独占写来避免访问冲突。
3、使用TEvent来实现同步。
至于上面那些东西怎么用,你就要看看帮助或查找资料了!如果要看例子,Delphi源码是最好的例子,
你可以看看Synchronize的工作原理。
 
我的step 方法
if (b is TComponentThread) then
(b as TComponentThread).ProcessEvents
else
if (b is TConnectorThread) then

(b as TConnectorThread).ProcessEvents
else
begin
// unknown brick type
end;

我在TConnectorThread, TComponentThread 类中维护了一个Fifo消息队列TPortList,
其中ProcessEvents 方法可能会处理消息队列中的消息,这个消息也是我自己定义
的类TMessage , TRequest, TNotification,
ProcessEvents 的方法如下,
var
r : TRequest;
n : TNotification;
begin
r := (bottom.SelectNextIncomingMessage) as TRequest;
if (r <> Nil) then
Handle_r(r);
n := (top.SelectNextIncomingMessage) as TNotification;
if (n <> Nil) then
Handle_n(n);
Result := (r <> Nil) or (n <> Nil);
在Handle_r, Handle_n 方法中可能会生成或者删除某个页面,
或者给页面添加某个VCL组件,
我现在的Thread.Execute 的方法是
if Assigned(b) then
begin
while not Terminateddo
begin
try
// Synchronize(Step);
Application.ProcessMessages;
Step;
except
On E : Exceptiondo
raise EThreadException.Create('Current Thread is Error');
end;
SemaphoreGet;
end;
end;






 
将SleepTime 设为固定值,比如sleep(20)试试………
 
我的Sleeptime 一直是个定值
 
你的消息队列是线程安全的吗?你要注意我上面说的第二条!
你的Step不应该用Synchronize执行,你应分的更细,只将有界面显示的部分用Synchronize
执行!不用再想别的了,你的问题几乎可以肯定是死锁问题!
你现在不要调试程序了,坐下来好好想一项你的系统结构,重新设计一下,充分考虑线程安全
问题然后再来修改程序!否则你永远不会有实质性的进展,会陷入一种泥潭!
 
接受答案了.
 
顶部