clq

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

"如果线程A锁住了记录1并等待记录2,而线程B锁住了记录2并等待记录1,这样两个线程就发生了死锁现象。"

如果只有一个线程锁定那么只要安全解锁了是不会死锁的,但特殊的情况是在 线程中使用了 sendmessage 而某个消息处理中又使用了该线程锁定就会形成死锁了.

原因是线程锁定是一个等待,而 sendmessage 又是一个等待,在消息队列中使用线程锁定同时在线程中使用 sendmessage 那么毫无疑问会发生死锁.

对于我来说这主要发生在已经做了线程,但新接到一个任务后不想再开线程而偷懒去使用定时器,这时死锁不可避免的发生了.为了验证将定时器间隔缩小你就会体会到了.

--------------------------------------------------

所以实际上是说不要混用线程和定时器处理可能访问同一资源的东西. (delphi , C++ 通用)

--------------------------------------------------

var
  i:Integer;
  user:TUserInfo;
begin
  //不应当用定时器实现,会死锁,因为  threadLock.Lock; 的其他线程是有可能发送 SendMessage 的,这时 sendmessage 会等待消息队列完成,
  //也就有可能会在 sendmessage 的时候等待定时器消息
  try
    ADOConnectionUser.Connected := True;
    ADOQueryUser.Close;
    ADOQueryUser.SQL.Clear;
    ADOQueryUser.SQL.Add('select * from AllOperators');
    ADOQueryUser.Open;




    //--------------------------------------------------
    //还是要锁定
    threadLock.Lock;
    try
      //TUserInfo.DelAllUser;
      for i := 0 to ADOQueryUser.RecordCount-1 do
      begin
        user:=TUserInfo.Create;
        user.userName := ADOQueryUser.fieldbyname('OperName').AsString;
        user.userPass := ADOQueryUser.fieldbyname('OperPsw').AsString;

        TUserInfo.AddUser(user.userName, user);
      end;

    finally
      threadLock.UnLock;
    end;
    //--------------------------------------------------


    MemoLog.Lines.Add('连接数据库刷新用户列表成功!')
  except
    //showme
    MemoLog.Lines.Add('连接数据库失败!')
  end;

end;

posted on 2012-05-02 12:36  clq  阅读(629)  评论(1)    收藏  举报