前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >技术笔记:Delphi多线程应用读写锁

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

作者头像
用户1105954
发布2018-01-12 18:10:21
1.4K0
发布2018-01-12 18:10:21
举报
文章被收录于专栏:mini188mini188

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

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

代码语言:javascript
复制
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;

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

代码语言:javascript
复制
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;

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

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

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2016-01-15 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档