线程交互,会不会两个线程同时挂起?

willflyz 2009-04-07 03:08:53
问题是这样的程序里面有两个线程,主线程用来做客户端和服务器通信的,当通信失败后将主线程挂起,再启用别一个check网络的线程去检查通信的情况,假设若干时间后通信恢复正常,那么Check的线程挂起,主线程继续执行.现在发现有一台电脑的两条线程都不动了,没有通信,check的线程也没反应了(check的次数是有控制的,不会永远check下去),不过主界面并没有死掉.请有经验的朋友帮忙分析一下是什么原因,谢谢!
1.是不是两个线程同时挂起了,什么原因?
2.另外想加一个线程或者Timer,定时去查看主线程,主线程为supended时就调用resume方法,这样不知是否可行?
...全文
144 10 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
willflyz 2009-04-07
  • 打赏
  • 举报
回复
谢谢各位回复!
僵哥 2009-04-07
  • 打赏
  • 举报
回复
看了半天,没发现这两个线程有存在的必要性。所有处理都被交换到主线程当中去执行,那么这两个线程似乎除了实现两个函数的相互切换调用和一个定时操作没有任何意思,这跟使用一个Timer当中执行如下代码有啥区别?
if Flag=1 then begin
GetDataFormServer;
if Not OK then Flag := 2;
end else begin
try
CheckConnect;
Flag := 1;
except
inc(iConnectCount);
...
end;
end;
willflyz 2009-04-07
  • 打赏
  • 举报
回复
代码太长了大概整理了一下,个人认为不会出现死锁的情况.因为两个线程是交换的,不会同时使用一个资源.


type
TThreadMain = class;
TThreadReConnect = class(TThread)
private
{ Private declarations }
a: TThreadMain;
procedure ReConnect;
protected
procedure Execute; override;
public
iConnectCount: word;
bReConnectOk: Boolean;
constructor create(p:TThreadMain);
destructor Destroy; override;
end;
//
TThreadMain = class(TThread)
private
{ Private declarations }
bOk: Boolean;
ThreadReConnect: TThreadReConnect;
procedure GetDataFormServer;
protected
procedure Execute; override;
public
constructor create(p:boolean);
destructor Destroy; override;
end;

{TThreadMain}

constructor TThreadMain.create(p:Boolean);
begin
inherited Create(p);
ThreadReConnect := TThreadReConnect.create(self);
end;

destructor TThreadMain.Destroy;
begin
ThreadReConnect.Terminate;
if ThreadReConnect.Suspended then
ThreadReConnect.Resume;
ThreadReConnect.WaitFor;
ThreadReConnect.Free;
inherited;
end;

procedure TThreadMain.GetDataFormServer;
begin
bOK := true;
try
{do something} //从服务器提取数据
except
bOK := false;
end;
end;

procedure TThreadMain.Execute;
var
i:Word;
begin
i := 2;
while not Terminated do
begin
Sleep(1000);
if i = 1 then
begin
Synchronize(GetDataFormServer);
if not bOk then
begin
ThreadReConnect.iConnectCount := 0;
if ThreadReConnect.Suspended then
ThreadReConnect.Resume;
self.Suspend;
end;
end;
i := i mod 60;
inc(i);
end;
end;

{TThreadReConnect}

constructor TThreadReConnect.create(p:TThreadMain);
begin
inherited Create(true);
a := p;
bReConnectOk := false;
end;

destructor TThreadReConnect.Destroy;
begin
inherited;
end;

procedure TThreadReConnect.Execute;
begin
while not Terminated do
begin
if Terminated then
break;
sleep(2000);
Synchronize(ReConnect);
if Terminated then
break;
end;
end;

procedure TThreadReConnect.ReConnect;
begin
bReConnectOk := false;
try
CheckConnect; //检查连接是否成功
bReConnectOk := true;
if a.Suspended then
a.Resume;
self.Suspend;
except
inc(iConnectCount);
if iConnectCount > 360 then
begin
showmessage('Can''t connect to Server,Please check network.');
PostMessage(frmMain.Handle, wm_close, 0, 0);
end;
end;
end;
xiaocha 2009-04-07
  • 打赏
  • 举报
回复
从你的说明来看,原理好像没什么问题,估计是代码有BUG
另外两个线程不同时工作,那为什么要做成两个线程呢?很奇怪的设计!
僵哥 2009-04-07
  • 打赏
  • 举报
回复
A和B相互拿着对方的资源不释放导致双方都在等待资源,这就是死锁.
starluck 2009-04-07
  • 打赏
  • 举报
回复


這樣子的就應該是使用消息通過向量來處理的是吧。

那你的第2個方式就可以,建立一個監控線程。 不過你一定要避免死鎖的問題(可以嘗試用臨界來避免)
willflyz 2009-04-07
  • 打赏
  • 举报
回复
CHECK 一定的次數後還是不成功就掛起重新 Resume 主線程?

--
不是一定次数不成功后就发消息给主窗口,退出程序.
starluck 2009-04-07
  • 打赏
  • 举报
回复
[Quote=引用楼主 willflyz 的帖子:]
问题是这样的程序里面有两个线程,主线程用来做客户端和服务器通信的,当通信失败后将主线程挂起,再启用别一个check网络的线程去检查通信的情况,假设若干时间后通信恢复正常,那么Check的线程挂起,主线程继续执行.现在发现有一台电脑的两条线程都不动了,没有通信,check的线程也没反应了(check的次数是有控制的,不会永远check下去),不过主界面并没有死掉.请有经验的朋友帮忙分析一下是什么原因,谢谢!
1.是不是两个线程同时挂起了,什…
[/Quote]


主線程通訊失敗,啟動CHECK 對吧。

CHECK 一定的次數後還是不成功就掛起重新 Resume 主線程?
willflyz 2009-04-07
  • 打赏
  • 举报
回复
谢谢僵哥回复,死锁是指?
客户端与服务器通信的时候死锁?这种情况遇到过,在通信的时候死掉了,不过这种现象是连主界面都动不了的.
僵哥 2009-04-07
  • 打赏
  • 举报
回复
死锁就会同时挂起。

16,747

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 语言基础/算法/系统设计
社区管理员
  • 语言基础/算法/系统设计社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧