具有易失性或锁定的属性

2024-01-04

我有一个带有支持字段的属性,我想使其线程安全(获取和设置)。 get和set方法除了设置和返回之外没有任何逻辑。

我认为有两种方法可以将逻辑封装在属性 self 中(易失性和锁定)。 我对两者的理解是正确的还是有错误?

以下是我的例子:

    public class ThreadSafeClass
    {
        // 1. Volatile Example:

        private volatile int _processState_1;
        public int ProcessState_1
        {
            get { return _processState_1; }
            set { _processState_1 = value; }
        }

        // 2. Locking Example:

        private readonly object _processState_2Lock = new object();
        private int _processState_2;
        public int ProcessState_2
        {
            get
            {
                lock (_processState_2Lock)
                {
                    return _processState_2;
                }
            }
            set
            {
                lock (_processState_2Lock)
                {
                    _processState_2 = value;
                }
            }
        }
    }

欲了解更多信息,请参阅J. Albahari 的很棒的网站 http://www.albahari.com/threading/part4.aspx#_The_volatile_keyword:

同步结构可以分为四类:

简单的拦截方法:

它们等待另一个线程完成或经过一段时间。Sleep, Join, and Task.Wait是简单的阻塞方法。

锁定结构:

这些限制了一次可以执行某些活动或执行一段代码的线程数量。独占锁定结构是最常见的——它们一次只允许一个线程进入,并允许竞争线程访问公共数据而不会互相干扰。标准的独占锁定结构是lock (Monitor.Enter/Monitor.Exit), Mutex, and SpinLock。非排他性的locking构造是Semaphore, SemaphoreSlim,以及reader/writer locks.

信号传导结构:

这些允许线程暂停,直到收到另一个线程的通知,从而避免低效的轮询。有两种常用的信号设备:事件等待句柄和监视器的等待/脉冲方法。框架4.0引入了CountdownEvent and Barrier类。

非阻塞同步构造:

它们通过调用处理器原语来保护对公共字段的访问。 CLR 和 C# 提供以下非阻塞构造:Thread.MemoryBarrier, Thread.VolatileRead, Thread.VolatileWrite, the volatile关键字,以及Interlocked class.


The volatile关键词:

volatile 关键字指示编译器在每次读取该字段时生成一个获取栅栏,并在每次写入该字段时生成一个释放栅栏。获取栅栏可防止其他读/写在栅栏之前移动;释放栅栏可防止其他读/写在栅栏之后移动。这些“半栅栏”比全栅栏更快,因为它们为运行时和硬件提供了更多优化空间。

碰巧的是,Intel 的 X86 和 X64 处理器总是对读取应用获取栅栏,对写入应用释放栅栏 — 无论您是否使用 volatile 关键字 — 因此,如果您使用这些处理器,则该关键字对硬件没有影响。然而,volatile确实会对编译器和 CLR 以及 64 位 AMD 和(在更大程度上)安腾处理器执行的优化产生影响。这意味着您不能因为您的客户端运行特定类型的 CPU 而更加放松。

将 volatile 应用于字段的效果可以总结如下:

First instruction   Second instruction  Can they be swapped?
Read                Read                No
Read                Write               No
Write               Write               No (The CLR ensures that write-write operations are never swapped, even without the volatile keyword)
Write               Read                Yes!

请注意,应用 volatile 并不会阻止先写后读的交换,这可能会造成脑筋急转弯。 Joe Duffy 用下面的例子很好地说明了这个问题:如果Test1 and Test2在不同的线程上同时运行,a 和 b 的值有可能都为 0(尽管两者都使用了 volatile)x and y):

class IfYouThinkYouUnderstandVolatile
{
  volatile int x, y;

  void Test1()        // Executed on one thread
  {
    x = 1;            // Volatile write (release-fence)
    int a = y;        // Volatile read (acquire-fence)
    ...
  }

  void Test2()        // Executed on another thread
  {
    y = 1;            // Volatile write (release-fence)
    int b = x;        // Volatile read (acquire-fence)
    ...
  }
}

MSDN 文档指出,使用 volatile 关键字可确保字段中始终存在最新值。这是不正确的,因为正如我们所看到的,先写后读可以重新排序。

这为避免 volatile 提供了强有力的理由:即使您理解此示例中的微妙之处,其他处理您代码的开发人员也会理解它吗?两个作业之间的完整栅栏Test1 and Test2(或锁)解决了问题。

The volatile关键字不支持传递引用参数或捕获的局部变量:在这些情况下,您必须使用VolatileRead and VolatileWrite方法。

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

具有易失性或锁定的属性 的相关文章

  • BufferBlock 连续

    我想使用以下方式实现消费者 生产者模式BufferBlock
  • JetBrains Rider 针对 4.5 框架,无法切换到 4.7

    基本上 当尝试添加不支持旧框架的 NuGet 包时 会出现错误 但是在项目配置中只有 4 5 可用 在项目创建过程中 不存在选择目标的选项 有什么方法可以正确配置它吗 I haven t found out how to set up NE
  • 当 foreach 块的内容具有 Conditional 属性时,C# 编译器是否会对其进行优化?

    我正在工作中编写一些调试代码 我想知道我所做的是否会损害性能 让我们看一下代码 foreach var item in aCollection Debug WriteLine item Name 我知道 Debug 类使用 Conditio
  • 如何检查号码是否只有唯一的数字?

    例如 2345 是唯一的数字 因为没有数字显示两次 但 3324 不是唯一的数字 因为 3 出现了两次 我尝试使用 但我 代码 显示但我没有得到数字我得到了数字 编辑 你不能使用字符串 number 10 number 100 number
  • C语言中没有循环可以打印数组吗?

    例如 在Python中 如果我们将一个列表作为数组 它会直接用一行代码打印整个数组 有什么办法可以用C语言实现同样的事情吗 简短回答 No 对表格上几乎所有问题的简短回答 用 C 语言做 X 工作能像用 Python 一样简单吗 No 长答
  • PartialView Action 正在调用自身

    我有 MVC 应用程序 它用于从主视图 ProductMaster 将 ProductAreaGrid 列表显示为 PartialView 并且它将在局部视图内将 CreateProductArea 作为 PartialView 我的 Gr
  • 从 Golang 调用 C 函数

    我想在 Golang 中编写控制器逻辑并处理 json 和数据库 同时在 C 中使用我的数学处理模型 在我看来 调用 C 函数的开销必须尽可能低 就像设置寄存器 rcx rdx rsi rdi 一样 执行一些操作fastcall 并获取 r
  • += 运算符在 C++ 中是如何实现的?

    这是我一直在思考的一个问题 但从未找到任何资源来说明这个问题的答案 事实上它不仅是为了 也适用于它的兄弟姐妹 即 等等 当然不是 考虑这个例子 int a 5 a 4 this will make a 9 现在考虑等效表达式 a a 4 T
  • 从二进制文件读取字节到 long int

    我有两个问题 我有二进制文件的数据 我想使用 read 函数读取前 8 个字节以签署 long int 但我不能 你知道我该怎么做吗 如何直接读取一块数据到字符串中 我可以像所示那样阅读吗 前任 ifstream is is open te
  • 主构造函数不再在 VS2015 中编译

    直到今天 我可以使用主构造函数 例如 public class Test string text private string mText text 为了能够做到这一点 在以前的 Visual Studio CTP 中 我必须将其添加到 c
  • 原子的 C++ 内存屏障

    在这方面我是个新手 谁能提供以下内存屏障之间差异的简化解释 窗户MemoryBarrier 围栏 mm mfence 内联汇编asm volatile memory 内在的 ReadWriteBarrier 如果没有简单的解释 一些好文章或
  • Web 文本编辑器中的 RTF 格式

    网络上是否有支持 RTF 格式文档输入的文本编辑器 我知道这对 webdev 来说有点奇怪 但我需要从数据库中读取 RTF 文档 并在基于 Web 的文本编辑器中对其进行编辑 然后将其存储回 RTF 中 在我在转换工具上投入太多资金之前 我
  • 重定向 std::cout

    我需要一个类 在其对象的生命周期内将一个 ostream 重定向到另一个 ostream 经过一番修补后 我想出了这个 include
  • C# 反序列化过程中创建指向父对象的指针

    我有这样的课程 Serializable public class child public Parent parent Serializable public class Parent public List
  • 使用 WinAPI 连接禁用的显示设备

    我的问题是启用禁用的监视器ChangeDisplaySettingsEx 我想这不是火箭科学 但经过一番挖掘后 它看起来仍然是不可能的 我找到了一种根据找到的 Microsoft 代码示例禁用所有辅助显示器的方法here https msd
  • 在 C# 窗口应用程序中运行 C/C++ 控制台应用程序?

    现在 我想开发一个简单的应用程序 因此我决定最快的编码方式是 C NET 但现在 我很难实现我需要的功能之一 我想做的是在 C 应用程序的窗口内运行 C C 控制台应用程序 就像在虚幻前端中一样 添加一点通信方式 以便我可以为控制台应用程序
  • 检查另一种形式的线程是否仍在运行

    我有一个涉及两个窗体的 Windows 窗体应用程序 子表单用于将数据导出到 CSV 文件 并使用后台工作者写入文件 当这种情况发生时 我隐藏了表格 当后台工作程序运行时 父窗体仍然处于活动状态 因此即使后台工作程序正在写入文件 用户也可以
  • 包含从代码隐藏 (ASP.NET C#) 到 ASPX 中的图像概述的图像列表 [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • Web API 2.0 使用 pascalcase 模型接收驼峰式命名的 JSON 数据

    我正在尝试对我的 Web API 进行 PUT 调用 我在 WebApiConfig cs 中设置了以下内容 以处理以驼峰形式将数据发送回我的 Web 项目 config Formatters JsonFormatter Serialize
  • 查找和替换正则表达式问题

    感谢这里对我其他问题的所有大力帮助 我开始掌握正则表达式 但我仍然对这个一无所知 我的代码是 StreamReader reader new StreamReader fDialog FileName ToString string con

随机推荐

  • 添加第二个主节点以实现 kubernetes 中的高可用性

    我能够按照文档操作并建立一个 kubernetes 集群 但我想添加第二个主节点我在第二个节点上尝试了此操作但看到错误 root kubemaster02 kubeadm init apiserver advertise address 1
  • 如何在 Firefox 中使用“Start”和“End”在 Iframe 中选择一个范围,例如输入元素中的“selectionStart”

    对于 Internet Explorer 我有当前的代码来选择 iframe 中的范围 并将 desingMode 设置为 on var Range window document selection createRange var obj
  • 以编程方式重新加载 Java JAR,无需重新启动 ColdFusion

    背景 从 ColdFusion 10 开始 可以包含来自自定义位置的 JAR http help adobe com en US ColdFusion 10 0 Developing WSe61e35da8d318518 106e125d1
  • PHP中如何判断一个字符串是否是一个数学语句?

    我有这个字符串作为例子 2 2 2 当评估时它应该返回int 2 我正在寻找一个函数 解析器 可以确定字符串中是否匹配任何类型的数学内容 更多示例 2 2 2 4 8 12 128 8 不需要评估和计算这些数学表达式 只需要一个函数来确定
  • 如何获取 Titan 中的索引键列表?

    我正在使用 Titan v0 3 1 并且希望查看我已经通过索引建立索引的键的列表createKeyIndex 我怎样才能做到这一点 在 Gremlin shell 中 您可以使用蓝图键可索引图 https github com tinke
  • Docker 中的 Apache / PHP error_log 位置

    我的 PHP 脚本有错误 例如 屏幕上显示 警告 require var www foo php 无法打开流 我在日志中哪里可以找到这个 I tried docker logs containerName 但它只显示访问日志 例如 192
  • SQLAlchemy 和多进程的连接问题

    我在一个项目中使用 PostgreSQL 和 SQLAlchemy 该项目由启动子进程的主进程组成 所有这些进程都通过 SQLAlchemy 访问数据库 我遇到可重复的连接失败 前几个子进程工作正常 但一段时间后会出现连接错误 这是一个 M
  • 检查安装的网络打印机是否在线

    我想检查打印机是否在线 为此我得到了 OpenPrinter 的打印机句柄 然后我想使用 PRINTER STATUS OFFLINE 在 PRINTER INFO 6 中使用 GetPrinter 结果总是0 如何获取打印机的离线状态 我
  • 向条形图添加水平线

    我正在尝试使用R plotly s bar输入plot 来生成一个带有水平布局的框的图 并在其背景中添加一条水平线 而不是在它们的顶部 另外 我希望这条线在每个方向上对称地延伸一个盒子单元 这就是我正在做的 plot df lt data
  • android 在模拟器或设备中执行?

    有什么方法可以知道我的应用程序是在模拟器上还是在设备上运行 我使用的代码片段适用于 Intel 和 ARM 模拟器 if Build MODEL contains google sdk Build MODEL contains Emulat
  • `npmaudit` 不断返回“您配置的注册表 (https://registry.npmjs.org/) 不支持审核请求。”。我怎样才能让它再次工作?

    这是我得到的错误 npm ERR code ENOAUDIT npm ERR audit Your configured registry https registry npmjs org does not support audit re
  • 带有 @init 块的 ANTLR4 词法分析器规则

    我在 ANTLR v3 语法文件中定义了这个词法分析器规则 它的数学文本用双引号引起来 我需要将其转换为 ANTLR v4 ANTLR 编译器抛出错误 语法错误 在匹配词法分析器规则时不匹配输入 期望冒号 在 init 行中 词法分析器规则
  • 使用 C# 无法正确更改应用程序图标

    我将应用程序的图标更改为新图标 方法是转到 Project MyProject Properties Icon and Maniferest 然后加载新图标 现在 在我的调试文件夹中 我的 exe 文件的图标出现了新图标 这没关系 但是当我
  • Google App Engine 删除了默认 GCS 存储桶。有办法恢复吗?

    我正在从应用程序的默认存储桶中删除一些文件 并且不小心还使用 gsutil rm 命令删除了存储桶本身 有没有办法恢复 重新创建 恢复它 我想继续使用免费配额而不启用计费 到目前为止我试图做的是 但我不确定它是否正确 我首先启用计费只是为了
  • HTML 表格忽略元素样式宽度

    HTML 表格忽略元素样式宽度 我有一个 HTML 表格 其中某些单元格具有很长的文本内容 我想使用 jQuery 为这些单元格指定宽度 以像素为单位 但渲染的表格只是忽略给定的宽度 有什么方法可以强制表格遵守这个宽度吗 Thanks JS
  • 测量 OpenCV FPS

    我正在寻找一种正确的方法来测量 openCV FPS 我找到了几种方法来做到这一点 但它们都不适合我 我测试过的第一个使用time t 开始和 time t 结束 我认为一旦它返回一个转储的函数作为 fps x 时间图 我真的无法想象 fp
  • 将行号添加到现有 HTML

    我正在尝试向现有的 html 添加行号 行高不等 许多类型的字体大小和图像 每条线看起来像 div div
  • 如何使用适用于 Node.js 的 AWS 开发工具包在 s3 上创建文件夹或密钥?

    我正在使用适用于 Node js 的 AWS 开发工具包在 s3 上创建文件夹或密钥 我在谷歌上搜索 但一无所获 有谁知道如何使用适用于 Node js 的 AWS SDK 在我的存储桶下创建文件夹 如何检查您的存储桶中是否已存在该文件夹
  • 实体组件系统和共享公共基础类型的多个组件

    我正在尝试为我的游戏引擎实现一个简单的 ECS 我知道我的实现并不是严格意义上的 ECS 但我正在重构我的代码以使其更加基于组件 到目前为止 我有以下课程 Entity 它是组件的容器 并且由于我希望我的实体具有相同类型的多个组件 因此它将
  • 具有易失性或锁定的属性

    我有一个带有支持字段的属性 我想使其线程安全 获取和设置 get和set方法除了设置和返回之外没有任何逻辑 我认为有两种方法可以将逻辑封装在属性 self 中 易失性和锁定 我对两者的理解是正确的还是有错误 以下是我的例子 public c