什么时候应该使用各个线程同步对象?

2024-04-18

在什么情况下应该使用以下每个同步对象?

  1. 读写锁
  2. 信号
  3. Mutex

  • 由于每次调用 post() 时 wait() 都会返回一次,因此信号量是一种基本的生产者-消费者模型 - 除了信号之外最简单的线程间消息形式。使用它们是为了让一个线程可以告诉另一个线程发生了它感兴趣的事情(以及发生了多少次),并用于管理对最多可以有固定有限数量的用户的资源的访问。它们提供多线程代码所需的排序保证。

  • 互斥体执行其表面上所说的操作 - “互斥”。它们确保一次仅由一个线程“持有”访问某些资源的权利。这保证了多线程代码所需的原子性和顺序。在大多数操作系统上,它们还提供相当复杂的等待行为,特别是为了避免优先级倒置。

请注意,信号量可以轻松地用于实现互斥,但由于信号量没有“所有者线程”,因此您无法使用信号量来避免优先级反转。因此它们并不适合所有需要“锁”的用途。

  • ReaderWriter 锁是对互斥体的优化,在存在大量争用的情况下,大多数访问都是只读的,并且受保护的数据结构允许同时读取。在这种情况下,仅当涉及作者时才需要排除 - 读者不需要相互排除。为了将读取器提升为写入器,所有其他读取器必须在获取写入器锁之前完成(或者如果他们也希望成为写入器,则中止并开始等待重试)。 ReaderWriter 锁在速度不快的情况下可能会更慢,因为它们在互斥锁上进行了额外的簿记操作。

  • 条件变量用于允许线程等待某些事实或事实组合为真,其中所讨论的条件比信号量中的“它已被戳”或互斥体中的“没有其他人使用它”更复杂读写器锁的写入者部分,或者对于读写器锁的读取器部分“没有写入者正在使用它”。它们还用于不同等待线程的触发条件不同但取决于部分或全部相同状态(内存位置或其他)的情况。

  • 自旋锁适用于当您在一个处理器或内核上等待很短的时间(例如几个周期),而另一个内核(或硬件,例如 I/O 总线)同时执行一些您关心的工作时关于。在某些情况下,它们比其他原语(例如信号量或中断)提供了性能增强,但必须极其小心地使用(因为无锁算法在现代内存模型中很困难)并且仅在被证明有必要时才使用(因为避免系统原语的聪明想法)通常是过早的优化)。

顺便说一句,这些答案不是特定于 C# 的(因此例如关于“大多数操作系统”的评论)。 Richard 提出了一个很好的观点,即在 C# 中,您应该在适当的情况下使用普通的旧锁。我相信监视器是一对滚入一个对象的互斥体/条件变量。

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

什么时候应该使用各个线程同步对象? 的相关文章

  • 自定义可视化 Web 部件属性 sharepoint

    我在 Visual Studio 2012 中创建可视 Web 部件属性时遇到问题 我被提及http msdn microsoft com en us library ee231551 aspx http msdn microsoft co
  • 实体框架 - 循环更新属性

    我正在尝试找到一种方法来循环 EF 对象的属性并更新这些属性的值 更具体地说 我有 50 个字段 其中最多填充 50 个下拉列表 所有 50 个可能都需要填充 也可能不需要填充 为了解决这个问题 我有一个中继器 最多可以创建 50 个 DD
  • 如何使用movntdqa避免缓存污染?

    我正在尝试编写一个 memcpy 函数 该函数不会将源内存加载到 CPU 缓存中 目的是避免缓存污染 下面的 memcpy 函数可以工作 但会像标准 memcpy 一样污染缓存 我正在使用带有 Visual C 2008 Express 的
  • 如何使用Task.WhenAny并实现重试

    我有一个创建多个基于 I O 的任务的解决方案 我正在使用Task WhenAny 来管理这些任务 但通常许多任务会由于网络问题或请求限制等原因而失败 我似乎找不到一个解决方案 使我能够在使用时成功重试失败的任务Task WhenAny 方
  • 多个源文件中包含包含“const”的头文件

    Why does not包含定义的头文件const并被多个源文件包含会产生编译错误multiple definition const in header file h const int num 5 int x Error Multiple
  • WPF MVVM将DataTable绑定到DataGrid不显示数据

    我有一个简单的控件 其中包含一个 DataGrid 其中 ItemsSource 绑定到 DataTable 当我填充 DataTable 时 我可以看到 DataGrid 中添加了行 但没有显示任何数据 我没有为此 DataGrid 使用
  • ApiController 操作无法从查询字符串解析数组

    使用 Visual Studio 2012 2 MVC4 Web 应用程序 我有请求发送到我的 ApiController 如下所示 http localhost api keys ids 1 ids 2 ids 3 我的印象是以下方法应该
  • 在 C 程序中追踪数组越界访问/写入的推荐方法

    考虑用 C 语言编写一些不太明显的算法的实现 例如 让它成为递归快速排序 我在 K N King 的 C 编程 现代方法 第二版 书中找到了它 可以从here http knking com books c2 programs qsort
  • 是否可以用 C# 为 Android 编写应用程序?

    我们都知道Android运行Dalvik VM程序 通常开发人员用 Java 编写程序并将其编译为 Dalvik 字节码 我想知道是否有可能创建一个可以接受 C 代码并将其编译为 Dalvik 字节码的编译器 嗯 这是一种选择 或者您可以在
  • 我应该使用函数还是无状态函子?

    这两段代码做同样的事情 如您所见 它将用于排序函数 哪个更好 我通常写后一种 但我看到一些程序员像以前那样做 struct val lessthan binary function
  • 选择要重写哪个基类的方法

    鉴于以下情况 class Observer public virtual void Observe Parameter p 0 template
  • 为什么 OOP 中静态类的最佳实践有所不同?

    我目前正在阅读有关 Java 最佳实践的内容 我发现根据这本书 https rads stackoverflow com amzn click com 0321356683我们必须优先选择静态类而不是非静态类 我记得在 C 最佳实践中 我们
  • #define, #ifdef #undef #endif

    我有以下代码 define PROC ADD void main void while 1 ifdef PROC ADD Do this code here then undefined it to run the code in the
  • java - 简单计算在多线程中比在单线程中花费更长的时间

    我试图了解如何利用多线程 我写了一个简单的程序来增加i 比方说 使用两种方式 400 000 次 单线程方式 0 到 400 000 和多线程方式 在我的例子中 4 次 0 到 100 000 线程数等于Runtime getRuntime
  • 更新插入 MongoDB 时如何防止出现“_t”字段?

    我有一个应用程序 它使用 MongoDB 的 C 驱动程序将 Upsert 插入 MongoDB 数据库 当我打电话给Update函数 我无法指定我要更新的类型 然后 t字段插入元素的类型 这是我用来更新插入的代码 collection U
  • 在 C# 中将 ulong 映射到 long ?

    我正在尝试将 ulong 映射到 long 反之亦然 将 uint 映射到 int 反之亦然 如下所示 为了将值保存在具有签名类型的 MS SQL 数据库中仅限整数和大整数 我这样做是因为我必须检查 在数据库中 一个数字 uint ulon
  • 如何并排显示 4 个三角形图案

    我无法让 4 个不同的三角形图案并排出现 这是一个控制台应用程序 这正是我试图通过使用嵌套 for 循环来实现的目标
  • 在 WPF 树视图中获取 FullPath?

    如果我以编程方式创建 WPF TreeView 例如 TreeView treeView lt added in the designer TreeViewItem rootNode new TreeViewItem rootNode He
  • 如何在Asp.Net Core中自定义开发者异常页面?

    这常见于ConfigureStartup cs 文件的方法具有如下所示的代码 if env IsDevelopment app UseDeveloperExceptionPage new DeveloperExceptionPageOpti
  • C++20 范围太多 |运营商?

    我在这段代码中使用 g 10 2 有谁知道为什么我最后收到编译器错误std views reverse on results3 include

随机推荐

  • 处理 read_html 对空网页的错误响应

    尝试抓取网页标题 但在名为 tweg com 的网站上遇到问题 library httr library rvest page url lt tweg com page get lt GET page url from httr pg lt
  • 即使在模拟器上,“adb root”命令也会返回“adbd 无法在生产版本中以 root 身份运行”?

    我正在尝试运行adb root模拟器上的命令 这是我连接的唯一设备 adb devices List of devices attached emulator 5554 device 但是 我收到以下错误消息 adb root adbd c
  • 如何将 Objective C 静态库导入到 Swift Framework 中?

    我正在编写一个动态框架 Proto framework 对于 Swift 中的 OS X 我想包含静态库中的代码 libstat a 这是用 Objective C 编写的 这是我得到的 Dynamic swift in Proto fra
  • Django,访问 PostgreSQL 序列

    在 Django 应用程序中 我需要创建一个订单号 如下所示 yyyymmddnnnn 其中 yyyy 年 mm 月 dd 日 nnnn 是 1 到 9999 之间的数字 我想我可以使用 PostgreSQL 序列 因为生成的数字是原子的
  • 如何取消订阅 C# 中特定类的事件的所有处理程序?

    基本前提 我有一个房间 当头像 进入 房间内的所有头像时 它会发布一个事件 当头像离开房间时 我希望它删除该房间的所有订阅 在将头像添加到新房间并订阅新房间的活动之前 如何才能最好地从房间中的所有活动中取消头像 代码是这样的 class R
  • 什么时候关闭光栅化步骤才有意义?

    在 vulkan 中 有一个创建管道所需的结构 名为VkPipelineRasterizationStateCreateInfo 在这个结构体中有一个名为rasterizerDiscardEnable 如果该成员设置为VK TRUE那么在光
  • 如何在 IE 的新选项卡中显示 PDF 而不下载它

    看来 IE 不允许直接打开 blob 您必须使用 msSaveOrOpenBlob 但有什么办法可以以某种方式将其转换吗 我确实需要将 PDF 显示到 IE 的新选项卡中而不下载它 或者至少用户不应该进行交互并且看不到它被下载到例如系统临时
  • 子集和问题

    最近我对子集和问题感兴趣 即在超集中找到零和子集 我在SO上找到了一些解决方案 此外 我还遇到了一个特定的问题solution http www skorks com 2011 02 algorithms a dropbox challen
  • 在多个子文件夹中搜索文件的VBA宏

    我有宏 如果我放入文件的单元格 E1 名称 则通过 C Users Marek Desktop Makro 目录进行宏搜索 找到它并将所需的值放入带有宏的原始文件的特定单元格中 是否可以在没有特定文件夹位置的情况下完成这项工作 我需要一些可
  • GCC ARM 汇编预处理器宏

    我正在尝试使用汇编 ARM 宏进行定点乘法 define MULT a b asm volatile SMULL r2 r3 0 1 n t ADD r2 r2 0x8000 n t ADC r3 r3 0 n t MOV 0 r2 ASR
  • 将集合从后台工作者 DoWork 传递到后台工作者已完成并执行 foreach

    我的目标是 用户在组合框中键入完整或部分计算机名 按钮单击事件启动后台工作人员将计算机名传递给 DoWork 方法 DoWork 方法在 ActiveDirectory 中搜索计算机名并将集合传递给 WorkerCompleted 方法 W
  • 动态IP地址的用户可以被阻止吗?

    现在我正在尝试构建一些东西 我的客户想要阻止某些向 Web 服务发出许多请求的 IP 地址 现在我想知道的是 如果我用动态 IP 地址阻止用户 他不能重置调制解调器并重新开始吗 你是对的 如果IP是动态的 尽管路由器重置可能不会立即改变它
  • sybase @@error 捕获错误的替代方法

    通常我会遇到这样的错误 EXECUTE STATEMENT SELECT ERR CODE ERROR 它处理简单的错误 如下面的查询 ERROR 返回值 insert into tab1 values 1 error attempt to
  • 如何从本地创建全局变量并存储其先前的值?

    在我的 pygame 游戏中 我希望子弹能够检测到它何时位于给定的命中框中 为此 我需要从本地创建一个全局变量 但是 每次出现新对象时 全局变量都会更新为新的碰撞盒 这不允许我跟踪之前的碰撞箱并检测子弹何时位于屏幕上的旧对象内 我该如何防止
  • 无法使用 JPA 获取与数据库的连接 - 缺少 derby 嵌入式驱动程序类

    我正在尝试使用 jpa 创建本地 derby 数据库 作为 JPA 实现 我使用 openjpa 并作为 sql 实现 derby 这是 persistence xml
  • Ruby 数组上未定义的方法“to_h”

    As per Ruby 数组文档 http ruby doc org core 2 2 0 Array html method i to h 有一个方法to h只要数组的每个元素是另一个包含两个元素的数组 就可以使用它将数组转换为哈希 以下
  • Android ListView,OnListItemClick,查找行id?

    我似乎无法找到如何获取我的 ListView OnListItemClick 以打开不同的活动 我知道我需要为 ListView 获取一些 row id 但我不知道如何做 现在 ListView 中的每一行都打开相同的活动 抱歉我的英语不好
  • JavaScript 的 for...in 循环如何处理多维数组?

    我在玩了一下 JavaScript 发现 至少对我来说 在通过 for in 循环处理多维数组时有奇怪的行为 所以我有这段代码
  • 在 C++ 中创建可修改的字符串文字

    是否可以在 C 中创建可修改的字符串文字 例如 char foo foo foo char afoo foo 0 afoo 2 g access violation 这会产生访问冲突 因为 foo 是在只读内存中分配的 我相信是 rdata
  • 什么时候应该使用各个线程同步对象?

    在什么情况下应该使用以下每个同步对象 读写锁 信号 Mutex 由于每次调用 post 时 wait 都会返回一次 因此信号量是一种基本的生产者 消费者模型 除了信号之外最简单的线程间消息形式 使用它们是为了让一个线程可以告诉另一个线程发生