ReaderWriterLockSlim 什么时候比简单的锁更好?

2024-01-05

我正在使用这段代码对 ReaderWriterLock 进行一个非常愚蠢的基准测试,其中读取的频率比写入的频率高 4 倍:

class Program
{
    static void Main()
    {
        ISynchro[] test = { new Locked(), new RWLocked() };

        Stopwatch sw = new Stopwatch();

        foreach ( var isynchro in test )
        {
            sw.Reset();
            sw.Start();
            Thread w1 = new Thread( new ParameterizedThreadStart( WriteThread ) );
            w1.Start( isynchro );

            Thread w2 = new Thread( new ParameterizedThreadStart( WriteThread ) );
            w2.Start( isynchro );

            Thread r1 = new Thread( new ParameterizedThreadStart( ReadThread ) );
            r1.Start( isynchro );

            Thread r2 = new Thread( new ParameterizedThreadStart( ReadThread ) );
            r2.Start( isynchro );

            w1.Join();
            w2.Join();
            r1.Join();
            r2.Join();
            sw.Stop();

            Console.WriteLine( isynchro.ToString() + ": " + sw.ElapsedMilliseconds.ToString() + "ms." );
        }

        Console.WriteLine( "End" );
        Console.ReadKey( true );
    }

    static void ReadThread(Object o)
    {
        ISynchro synchro = (ISynchro)o;

        for ( int i = 0; i < 500; i++ )
        {
            Int32? value = synchro.Get( i );
            Thread.Sleep( 50 );
        }
    }

    static void WriteThread( Object o )
    {
        ISynchro synchro = (ISynchro)o;

        for ( int i = 0; i < 125; i++ )
        {
            synchro.Add( i );
            Thread.Sleep( 200 );
        }
    }

}

interface ISynchro
{
    void Add( Int32 value );
    Int32? Get( Int32 index );
}

class Locked:List<Int32>, ISynchro
{
    readonly Object locker = new object();

    #region ISynchro Members

    public new void Add( int value )
    {
        lock ( locker ) 
            base.Add( value );
    }

    public int? Get( int index )
    {
        lock ( locker )
        {
            if ( this.Count <= index )
                return null;
            return this[ index ];
        }
    }

    #endregion
    public override string ToString()
    {
        return "Locked";
    }
}

class RWLocked : List<Int32>, ISynchro
{
    ReaderWriterLockSlim locker = new ReaderWriterLockSlim();

    #region ISynchro Members

    public new void Add( int value )
    {
        try
        {
            locker.EnterWriteLock();
            base.Add( value );
        }
        finally
        {
            locker.ExitWriteLock();
        }
    }

    public int? Get( int index )
    {
        try
        {
            locker.EnterReadLock();
            if ( this.Count <= index )
                return null;
            return this[ index ];
        }
        finally
        {
            locker.ExitReadLock();
        }
    }

    #endregion

    public override string ToString()
    {
        return "RW Locked";
    }
}

但我知道两者的表现或多或少是相同的:

Locked: 25003ms.
RW Locked: 25002ms.
End

即使读取频率比写入频率高 20 倍,性能仍然(几乎)相同。

我在这里做错了什么吗?

亲切的问候。


在你的例子中,睡眠意味着一般来说没有争议。无竞争锁速度非常快。为此,您需要一个争辩的锁;如果有writes在该争论中,它们应该大致相同(lock甚至可能更快) - 但如果是的话mostly读取(很少有写入争用),我希望ReaderWriterLockSlim锁定以超越lock.

就我个人而言,我更喜欢这里的另一种策略,使用引用交换 - 因此读取始终可以读取而无需检查/锁定/等。写入将其更改为cloned复制,然后使用Interlocked.CompareExchange交换引用(如果另一个线程在此期间改变了引用,则重新应用它们的更改)。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

ReaderWriterLockSlim 什么时候比简单的锁更好? 的相关文章

  • iPhone SDK - 在后台线程中运行重复进程

    我有一个iPhone我想在其中每隔一段时间在后台执行一个方法的应用程序1第二 所以在我的主线程中 我有以下代码UIViewController viewDidLoad NSTimer timerWithTimeInterval 1 0 ta
  • 将字符串从非托管代码传递到托管

    我在将字符串从非托管代码传递到托管代码时遇到问题 在我的非托管类中 非托管类 cpp 我有一个来自托管代码的函数指针 TESTCALLBACK FUNCTION testCbFunc TESTCALLBACK FUNCTION 接受一个字符
  • 使用 C# 在 WinRT 中获取可用磁盘空间

    DllImport kernel32 dll SetLastError true static extern bool GetDiskFreeSpaceEx string lpDirectoryName out ulong lpFreeBy
  • 使用 Google Analytics API 在 C# 中显示信息

    我一整天都在寻找一个好的解决方案 但谷歌发展得太快了 我找不到有效的解决方案 我想做的是 我有一个 Web 应用程序 它有一个管理部分 用户需要登录才能查看信息 在本节中 我想显示来自 GA 的一些数据 例如某些特定网址的综合浏览量 因为我
  • 为什么模板不能位于外部“C”块内?

    这是一个后续问题一个答案 https stackoverflow com questions 4866433 is it possible to typedef a pointer to extern c function type wit
  • 在 ASP.Net Core 2.0 中导出到 Excel

    我曾经使用下面的代码在 ASP NET MVC 中将数据导出到 Excel Response AppendHeader content disposition attachment filename ExportedHtml xls Res
  • 使用向量的 merge_sort 在少于 9 个输入的情况下效果很好

    不知何故 我使用向量实现了合并排序 问题是 它可以在少于 9 个输入的情况下正常工作 但在有 9 个或更多输入的情况下 它会执行一些我不明白的操作 如下所示 Input 5 4 3 2 1 6 5 4 3 2 1 9 8 7 6 5 4 3
  • 编译的表达式树会泄漏吗?

    根据我的理解 JIT 代码在程序运行时永远不会从内存中释放 这是否意味着重复调用 Compile 表达式树上会泄漏内存吗 这意味着仅在静态构造函数中编译表达式树或以其他方式缓存它们 这可能不那么简单 正确的 他们可能是GCed Lambda
  • 如何在 Team Foundation 上强制发表有意义的签入评论?

    我有一个开发团队有一个坏习惯 他们写道poor签入评论 当我们必须在团队基础上查看文件的历史记录时 这使得它成为一场噩梦 我已经启用了变更集评论政策 这样他们甚至可以在签到时留下评论 否则他们不会 我们就团队的工作质量进行了一些讨论 他们很
  • C 中的位移位

    如果与有符号整数对应的位模式右移 则 1 vacant bit will be filled by the sign bit 2 vacant bit will be filled by 0 3 The outcome is impleme
  • 什么是 C 语言的高效工作流程? - Makefile + bash脚本

    我正在开发我的第一个项目 该项目将跨越多个 C 文件 对于我的前几个练习程序 我只是在中编写了我的代码main c并使用编译gcc main c o main 当我学习时 这对我有用 现在 我正在独自开展一个更大的项目 我想继续自己进行编译
  • 将日期参数传递给对 MVC 操作的 ajax 调用的安全方法

    我有一个 MVC 操作 它的参数之一是DateTime如果我通过 17 07 2012 它会抛出一个异常 指出参数为空但不能有空值 但如果我通过01 07 2012它被解析为Jan 07 2012 我将日期传递给 ajax 调用DD MM
  • EPPlus Excel 更改单元格颜色

    我正在尝试将给定单元格的颜色设置为另一个单元格的颜色 该单元格已在模板中着色 但worksheet Cells row col Style Fill BackgroundColor似乎没有get财产 是否可以做到这一点 或者我是否必须在互联
  • 作为字符串的动态属性名称

    使用 DocumentDB 创建新文档时 我想设置属性名称动态地 目前我设置SomeProperty 像这样 await client CreateDocumentAsync dbs db colls x new SomeProperty
  • GDK3/GTK3窗口更新的精确定时

    我有一个使用 GTK 用 C 语言编写的应用程序 尽管该语言对于这个问题可能并不重要 这个应用程序有全屏gtk window与单个gtk drawing area 对于绘图区域 我已经通过注册了一个刻度回调gtk widget add ti
  • 方法参数内的变量赋值

    我刚刚发现 通过发现错误 你可以这样做 string s 3 int i int TryParse s hello out i returns false 使用赋值的返回值是否合法 Obviously i is but is this th
  • 窗体最大化时自动缩放子控件

    有没有办法在最大化屏幕或更改分辨率时使 Windows 窗体上的所有内容自动缩放 我发现手动缩放它是正确的 但是当切换分辨率时我每次都必须更改它 this AutoScaleDimensions new System Drawing Siz
  • 如何在 C# 中播放在线资源中的 .mp3 文件?

    我的问题与此非常相似question https stackoverflow com questions 7556672 mp3 play from stream on c sharp 我有音乐网址 网址如http site com aud
  • 如何将字符串“07:35”(HH:MM) 转换为 TimeSpan

    我想知道是否有办法将 24 小时时间格式的字符串转换为 TimeSpan 现在我有一种 旧时尚风格 string stringTime 07 35 string values stringTime Split TimeSpan ts new
  • 为什么 strtok 会导致分段错误?

    为什么下面的代码给出了Seg 最后一行有问题吗 char m ReadName printf nRead String s n m Writes OK char token token strtok m 如前所述 读取字符串打印没有问题 但

随机推荐

  • 重置等待计时器

    来自 MSDN The 取消等待定时器 http msdn microsoft com en us library ms681985 aspx函数不会改变定时器的信号状态 它会在定时器设置为有信号状态之前停止定时器并取消未完成的 APC 因
  • 类型错误:int() 参数必须是字符串、类似字节的对象或数字,而不是“datetime.datetime”

    我试图为我的所有模型添加 created at 字段 但收到以下错误 TypeError int argument must be a string a bytes like object or a number not datetime
  • twitter bootstrap 3.0 typeahead ajax 示例

    Bootstrap 2 有很多 typeahead ajax 示例 例如这里twitter bootstrap typeahead ajax 示例 https stackoverflow com questions 9232748 twit
  • 从数据框创建稀疏矩阵

    我正在做一项作业 尝试为 Netflix 奖项数据构建协作过滤模型 我使用的数据位于 CSV 文件中 我可以轻松地将其导入到数据框中 现在我需要做的是创建一个稀疏矩阵 其中用户作为行 电影作为列 每个单元格都由相应的评级值填充 当我尝试绘制
  • 另一个本地 gem 的“gem.add_dependency”

    我正在创建一个 gem 它依赖于另一个已发布的 gem 在my gem gemspec 我已将依赖项添加到另一个 gem gem add dependency other gem gt 1 0 0 现在 我发现了一个可以调整的功能其他宝石
  • 如何仅在增量代码上运行 Maven checkstyle 插件

    我想向我们的应用程序添加自动代码审查功能 目前我们使用maven来进行构建 我遇到了 Maven checkstyle 插件 但希望它仅在添加的增量代码上运行 而不是在旧代码上运行 我可以使用这个插件实现这个目标吗 如果是 请提供有关如何操
  • Shiny DataTable:使用按钮扩展保存完整的 data.frame

    我正在将 DataTables 与 Shiny 一起使用 通过按钮扩展 用户可以下载或打印数据表中的数据 但仅下载 打印行的可见部分 我想改变这种行为 以便可以下载包含所有行的完整 data frame 这可以通过按钮扩展实现吗 还是我必须
  • jQuery AJAX 回调中抛出的异常被吞没?

    除了向每个回调添加 try catch 块之外 还有什么方法可以处理 jQuery 中 AJAX 回调引发的异常吗 在这种情况下不会调用错误函数 ajax url myurl rails success function data thro
  • 向通用 RecyclerView 适配器添加点击侦听器

    Edit 因为它是一个通用适配器 并不简单 而且我知道添加点击侦听器的方法 在以下情况下这样做并不是一个好的做法onCreateViewHolder 所以这就是为什么我需要更好的建议 我创建了一个RecyclerView 的通用适配器 in
  • 在没有序列化器的对象上使用 JSON.stringify 需要标记为实验性的

    在Android Studio中使用kotlin插件1 3 10 当我尝试将一个简单类的对象字符串化为 JSON 时 它不会编译 此声明是实验性的 其用法必须标有 kotlinx serialization ImplicitReflecti
  • r 检查软件包版本是否大于 x.y.z

    R 包的版本号如 1 97 1 我可以检查版本号是多少 packageVersion data table 在我的计算机上 返回 1 10 0 我想要做的是检查 data table 版本是否比 1 9 7 更新 因为 1 9 7 之后的版
  • PHP 和 Javascript 交互

    我需要在这里澄清一些事情 我有一个网站 每次在浏览器中重新加载该网站时 都会更新两个变量的值 该页面显然是一个 HTML 页面 但变量是通过 javascript 函数更新的 该页面在我的服务器上运行 PHP 可以检索这些变量的值并使用它们
  • 验证命名约定? C# [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • 如何在 R 中使用 ggplot2 制作默认自定义主题

    当我尝试使用应用定制主题时ggplot2它会收到如下错误 Error in FUN text 1L Theme element text has NULL property family face size hjust vjust angl
  • 图像文件中的二维码解码器(反应本机)

    我正在寻找一种从反应本机 特别是ios 中的图像文件中解码二维码的方法 我知道世博会提供相机扫描仪解决方案 但我需要文件解码器 很感谢任何形式的帮助 您可以使用jsQR 库 https github com cozmo jsQR从图像文件中
  • 将元素与 HTML 表格单元格的底部对齐

    我的 HTML 表格的一个单元格中有多个元素 我希望一些元素与单元格的底部对齐 一些元素与顶部对齐 我无法让元素与底部对齐 我的桌子是 tr td style background color 007CE2 p test br anothe
  • 带有命名空间的 XML 文档上的 XPath

    我有这个带有命名空间的 XML 文档 并且我想使用 XPath 提取一些节点 这是文件
  • Azure 函数在 azure 门户上显示 0 次执行

    我是一个蔚蓝新手 我的设置如下 我有一个 IoT 中心 一个事件中心 一个 Azure 函数 其想法是将消息发送到 IoT 中心 根据某种消息类型将它们路由到事件中心 并使用该函数处理这些事件 我创建了一个示例控制台应用程序 用于将消息从我
  • Ionic 2 范围触摸事件

    我正在尝试在输入末尾使用 Ionic 2 获取范围滑块的值 In the 文档 http ionicframework com docs v2 api components range Range output events唯一可用的事件是
  • ReaderWriterLockSlim 什么时候比简单的锁更好?

    我正在使用这段代码对 ReaderWriterLock 进行一个非常愚蠢的基准测试 其中读取的频率比写入的频率高 4 倍 class Program static void Main ISynchro test new Locked new