D5中关于的TCriticalSection一个问题,急!(在线等待)(50分)

E

ebeggar

Unregistered / Unconfirmed
GUEST, unregistred user!
我定义了一个TCriticalSection类型,如rCS,
在线程1中,
rCS.Enter;
try
...
//代码段1
finally
rCS.Leave;
end;

在线程2中,
rCS.Enter;
try
...
//代码段2
finally
rCS.Leave;
end;

问题是当线程1的代码段1执行时间稍长,也就是还没有执行到rCS.Leave时,线程2就开始运行了,这时执行rCS.Enter就会使所有线程停止。
该如何解决这个问题?
 
应该是线程2停止了,线程一继续运行,
1。减少被锁定的代码工作负荷,
2。改用其他同步措施比如互斥什么的
 
我现在是线程1停止了,线程2也进不去,不知为什么会这样,非要用互斥?
 
不会把是不是你的rCS.Leave没有工作啊,或者是有逻辑问题
我这么用过很多次,都没出什么问题呀?
 
不会的啊
我所有的地方都是使用如下语句:
rCS.Enter;
try
...
...
finally
rCS.Leave;
end;

我再仔细检查检查
 
除非你是这样用
TThread1 = ...
private
rCS : TCrit...
...
end.

TThread2 = ...
private
rCS : TCrit...
...
end.

这样Thread1和Thread2的rCS并不是同一个,当然会这样。
或者是这样:
TYourThread = ...
private
rCS : TCrit...
...
end.

...
Var
t1, t2 : TYourThread;
begin
...
end.
这样t1的rCS和t2的rCS并不是同一个,也会这样。
解决办法就是把rCS做成全局变量。
 
to 猛禽:
我定义的rCS:TCriticalSection是全局变量
 
那就奇怪了,和无忌兄一样的疑问,为什么我们用都没有问题呢[:(]
 
我也觉得奇怪,更无奈!
探讨一下,如果线程1中的代码段1没有执行完毕(可能花的时间较长),这时进入到线程2的rCS.Enter语句,请问,线程2是等待吗?
 
线程2会在rCS.Enter处被挂起。
实在不行你换成Event来试试。
 
郁闷,还是没能搞定
to 猛禽:
我的问题是线程2挂起后,程序就等于死掉了,不再接受用户指令。
如果这样都不行,那delphi中的‘临界区’岂不没什么意义了
 
估计你线程处理有问题,
线程1结束的条件有几个,可能因为线程2运行后,某个条件始终达不到,造成线程1不能结束
要看看你代码了
你线程2挂起后,程序等于死掉了?
那你线程2的代码估计问题不小,正常的线程挂起,不应该影响到主线程
 
非常谢谢Avenir。
其实我程序结构是这样,线程1是一个数据扫描程序,线程2就是主线程。
在数据量小的时候,程序运行稳定,当扫描到的数据量大的时候,线程1的程序段运行需要时间,这时如果触发主线程中的某个事件,就引起线程1停止,主程序‘死’掉。
如果主程序中去掉Enter和Leave语句(如下),则会引起数据库错误,因为我要同时读写
rCS.Enter
...
rCS.Leave
同一数据表,我再去优化优化程序,看又没有办法
 
如果线程1拥有临界区,那么线程1每次调用Enter都会增加临界区的计数,在其他线程能够拥有临界区之前,必须调用足够多次的Levave,以便使引用计数降为零。不知你的程序是不是这样?
按照你的要求,我倒觉得没有必要同步两个线程,你可以将降低线程1执行优先级。这样的话如果线程2需要工作,可以保留县城1的工作状态,挂起线程1,完成后再重新恢复线程1的执行。就可以避免同时读写数据库了。
 
to tingjie:
我理解的临界区的用法是不需要自己去做引用计数的啊,应该由系统自动处理,别的线程没有Leave的时候,另一个线程是不能Enter的。
你建议的不用临界区,降低线程2的优先级别可以考虑,我试试。
 
搞定了,谢谢tingjie,我用的是降低线程2的优先级的方法!
再次谢谢!
分数给各位奉上,只有一点点,不成敬意
 
多人接受答案了。
 
顶部