• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    公众号

技术笔记:Delphi多线程应用读写锁

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

在多线程应用中锁是一个很简单又很复杂的技术,之所以要用到锁是因为在多进程/线程环境下,一段代码可能会被同时访问到,如果这段代码涉及到了共享资源(数据)就需要保证数据的正确性。也就是所谓的线程安全。之前写过一篇着于Java线程安全的博客:链接

 

我是在写一个服务端程序时应用到读写锁,在一个内存缓存。先来看看排斥锁的写法,代码如下:

 

function TValueCalc.GetValue(const key: string): TCache;
var
  objCache: TCache;
begin
  Result := nil;  
  //加锁
  FRead2Lock.Enter;
  try
    objCache := GetCacheInstance.GetCache(sKey);
    if objCache <> nil then
    begin
      //缓存正在更新,直接退出,不让线程等待,以提高性能
      if objCache.IsUpdating then
        Exit;
      //是否过期,未过期直接返回
      if MilliSecondsBetween(Now, objCache.LastTime) < Expires then
      begin
        Result := objCache;
        Exit;
      end;
      
      objCache.IsUpdating := True;
    end;
    //更新缓存
    Result := UpdateCache(key);
  finally
    //释放锁
    FRead2Lock.Leave;
  end;
end;

 

 

但是这个缓存有一个特点,就是每个缓存项存活的时间很短,这就会导致大量的缓存更新操作,而这些更新操作由于业务不同耗时也不同。这就导致线程都在等待缓存的更新。为了解决这个问题引入了读写锁。让读锁可以在写数据时释放,让后面的线程继续执行查找缓存数据。

function TValueCalc.GetValue(const key: string): TCache;
var
  objCache: TCache;
begin
  Result := nil;      
  FRead2Lock.Enter;
  try
    objCache := GetCacheInstance.GetCache(sKey);
    if objCache <> nil then
    begin
      //缓存正在更新,直接退出,不让线程等待,以提高性能
      if objCache.IsUpdating then
        Exit;
      //检查缓存是否过期
      if MilliSecondsBetween(Now, objCache.LastTime) < Expires then
      begin
        Result := objCache;
        Exit;
      end;
      
      objCache.IsUpdating := True;
    end;
    
    //先释放读锁,后面线程可以继续读数据
    FRead2Lock.Leave;
    //加写锁
    FWriteLock.Enter;
    try
      //更新缓存
      Result := UpdateCache(key);
    finally
      //数据更新完毕,重新加上读锁
      FRead2Lock.Enter;
      //释放写锁
      FWriteLock.Leave;
    end;
  finally
    //释放读锁
    FRead2Lock.Leave;
  end;
end;

读写锁是在进行写数据前先释放掉读锁,然后马上加上写锁,这样后续读缓存的线程就可以继续执行,不会等待。而同时写缓存已经上锁,这样就不会资源冲突。

 

读写锁这样就可以大大提升读缓存的性能,也不会影响到缓存的更新了。

 


鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
编写一个单独的WebServiceforDelphi发布时间:2022-07-18
下一篇:
Delphi与DirectX之DelphiX(52):TDIB.DoSaturation();发布时间:2022-07-18
热门推荐
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap