如何resume和suspend线程?急!哪位大侠能在5月10日内回答这个问题,另送上300分。(200分)

  • 主题发起人 主题发起人 toxing
  • 开始时间 开始时间
T

toxing

Unregistered / Unconfirmed
GUEST, unregistred user!
我想使用一个线程作为服务,平时挂起,需要时由主线程启动(resume)。
使用tthread1:=thread.create(true)创建它。其中
procedure tthread1.Execute;
begin
while not Terminateddo
begin
synchronize(writememo);
suspend;
end;
end;
(其中,writememo是我作为测试用的往主form的memo中写的过程)
在主form中,我使用下述代码在一个过程中调用
while not tthread1.Suspended do
begin
sleep(100);
end;
tthread1.Resume;
若只调用一次该过程一切正常,但若顺序调用两次以上,则程序在
while not tthread1.Suspended do
处挂死,就是说线程运行一次后一直没停止,memo中只有第二次调用时留下的写记录。
也就是说第一次运行的线程根本没写记录,难道是它一直在执行?
我到底该如何写这个处理呢?
 
1.能行,但这样每次运行都至少多了一次sleep,该如何避免?我把ProcessMessages提到
while not tthread1.Suspended do
前仍会遗漏信息。
2.对线程是否挂起有没有什么类似waitfor之类的等待处理,或获得相应的消息?
3.如果不使用写memo的操作,只是做了与界面无关的操作,应该不用ProcessMessages吧。
btw:如何分配附加的300分?
 
1.将Sleep直接删掉就行了——有了ProcessMessages,这一句就纯属多余了。还有一点——
在Sleep的时候,VCL是不会处理任何事件的——它在Sleep,此时可能在工作的只是别的线程。
2.只有Terminate可以WaitFor,而挂起就不行,如果要在挂起时获得消息,你可以试着在
Suspend的时候向Form1发一个自定义的消息。在Delphi深度历险里有一个TSimpleThread控件,
对TThread封装得非常好,有OnSuspend,OnResume,OnActivate...事件,使用起来非常方便。
如果找不到的话我可以Mail给你。
3.我不是很清楚,不过我认为只要在线程中调用了VCL的方法(不论是显式的或是隐式的),
都应该给VCL一个机会以处理这些事件。
200分已经太多了。 :)
 
creation-zy,
1.问题是我这里只是简单说明,实际的线程中进行了一些tcp连接操作,却没有VCL的
方法。但很可能是需要等待的,这时应该怎么办?
2.只要能解决问题,再多分也是值得的。:)不过这些问题还是请尽快回答。急着用。
3.你把TSimpleThread发MAIL给我吧,我连了几次,一直连不上下载点。谢了。
 
1.请将问题说得再具体一点。如果你使用的是Delphi带的Socket控件,建议在其相应的事件中
写相应的处理过程;如果用的是Windows的Socket调用,则可以通过设置阻塞模式来实现线程
的阻塞。不过,我认为ProcessMessages是有必要的,因为只要程序代码不全部都在Thread中,
就肯定是由主线程来处理的,如果主线程没有时间处理Thread之外的代码,就很有可能造成
Synchronize的无限期等待。
2.我也想呀,可是肚子里实在没货,我这不正在一边喝墨水一边写吗? :P
3.Your Email?
 
1,我的线程里主要操作就是调用了一个第三方用C写的dll,由DLL进行一个远端TCP连接,
并往TCP内写东西。所以没法用socket控件。:(
2.我的mail是zhengx@21cn.com,谢了。
3.看来creation-zy你对线程还是很了解的,有空看看我另一问题:
http://www.delphibbs.com/delphibbs/dispq.asp?lid=496295
谢了。
 
已看过tsimplethread的代码,但对我这里要求的等待没什么帮助。由于我这线程中的操作
比较耗时,每次主线程resume该线程前还要往线程内一个数组写参数,为了保证线程安全,
我只能在线程挂起时写,所以我只好每次都用sleep等待线程结束了。
creation-zy,还有没什么好建议,没的话我就结束这个问题了。
 
看一看TThread的WaitFor函数代码:
while MsgWaitForMultipleObjects(1, H, False, INFINITE,
QS_SENDMESSAGE) = WAIT_OBJECT_0 + 1do
PeekMessage(Msg, 0, 0, 0, PM_NOREMOVE)
它所使用的技术也无非是通过一个无限循环等待线程结束事件的发生,在线程没有结束的时候,
还是要进行一些消息的处理。因此,我认为在程序中使用循环来等待线程的挂起并不是什么下策。
不过,为了提高效率,建议将Sleep的参数设为1。
刚才喝了一点墨水,又有了几个点子:
1.如果可能的话,可以采用Terminate而不是Suspend,将初始化过程放在Execute之外,这样的
好处是当线程再次被创建的时候可以直接进入工作状态,并且可以WaitFor了。
2.看一看WaitForSingleObject以及其它API函数的用法,对TSimpleThread的功能进行扩充,使其
可以WaitForSuspend。
还有一点需要注意:Synchronize是通过向主线程发送一个消息来使得其中的过程在主线程中
被执行的,因此,如果要多次调用它,ProcessMessages是绝对有必要的。
根据你所说的情况,我认为可以将循环整个放到TThread的Execute方法里去——如果仅仅是调用
DLL,没有必要使用Synchronize。只要在Create之前一次性将数据都准备好,然后Execute and
WaitFor就可以了。
 
请问你们用sleep有没有出现过有时醒不过来,有时又会?
我就碰上了这种奇怪的事情
而且DELPHI5开发人员指南讲线程一章中也说会有点问题,但不是明确说就是这个问题。
 
哈哈! I got it!
procedure TForm1.Button1Click(Sender: TObject);
var
i:Integer;
begin
for i:=1 to 5do
begin
while not tthread1.Suspended do
begin
sleep(100);
Application.ProcessMessages;
//关键是这一句
//因为在向Memo1写文本的时候要进行重绘操作
//如果不让VCL有机会处理它,就会永远等待重绘
end;
tthread1.Resume;
end;
end;
procedure TThread1.WriteMemo;
begin
with Form1.Memo1do
begin
Lines.Add(IntToStr(Tag));
Tag:=Tag+1;
end;
end;
 
看看 msdn 关于 sleep。
public static native void sleep( long millis )
Causes the currently executing thread to sleep
(temporarily cease execution) for the specified number of milliseconds.
The threaddo
es not lose ownership of any monitors
当线程执行sleep(1000),线程并没有交出所有权,所以于事无补。
每当我看到 sleep函数的时候,我总会想起dos编程时代,那都是5,6年前的事了。很快是吗?
都过时了,sleep也一样。
我从不用sleep,你还不如用 替换WaitForSingleObject(hVar, 1000);因为他才真正挂起,
交出cpu控制权。
好好看 WaitForSingleObject(hVar, 1000);等相关的信号量控制函数,那是windows 多线程的精髓。
 
接受答案了.
 

Similar threads

S
回复
0
查看
3K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
2K
SUNSTONE的Delphi笔记
S
I
回复
0
查看
584
import
I
后退
顶部