多个线程调用同一个函数

2024-01-12

假设我们有多个线程都调用同一个函数:

def foo 
  # do stuff ...
end

100.times do |i|
  Thread.new do
    foo
  end
end

如果当前有两个或多个线程foo,它们是否共享相同的局部变量foo?

这涉及到我的第二个问题。线程是否具有单独的堆栈帧,或者它们在单个进程内共享堆栈帧吗?具体来说,当多个线程各自调用foo和之前foo返回,是否有多个副本foo在堆栈上,每个变量都有自己的局部变量,或者只有一个副本foo在堆栈上?


是的,它们共享相同的变量。这是线程的关键元素,在只读上下文中很好,但是如果它们写入任何这些变量,则需要使用Mutex and synchronize线程,因此在任何给定时间只有一个可以更改变量。有时他们可能会调用间接更改数据的方法,因此在决定是否需要同步之前,您需要完全了解系统。

至于你的第二个问题,如果我明白你在问什么,他们有单独的堆栈框架,but它们仍然在内存中共享相同的数据。

在下面的示例中,澄清了局部变量zip is由多个线程共享,因为它是在当前作用域中定义的(线程不会更改作用域,它们只是在当前作用域中启动一个单独的并行执行线程)。

zip = 42

t = Thread.new do
  zip += 1
end

t.join

puts zip # => 43

这里的连接救了我,但显然,如果我将其保留在那里,那么线程中根本没有任何意义。如果我执行以下操作,将会很危险:

zip = 42

t = Thread.new do
  zip += 1
end

zip += 1

puts zip # => either 43 or 44, who knows?

那是因为你基本上有两个线程都试图修改zip同时。当您访问网络资源或增加数字等时,这一点变得很明显,如上所述。

然而,在下面的示例中,局部变量zip是在一个全新的作用域内创建的,因此两个线程实际上并没有同时写入同一个变量:

def foo
  zip = 42
  zip += 1 # => 43, in both threads
end

Thread.new do
  foo
end

foo

有两个并行堆栈被管理,每个堆栈内部都有自己的局部变量foo method.

然而,下面的代码是危险的:

@zip = 42 # somewhere else

def foo
  @zip += 1
end

Thread.new do
  foo
end

foo

puts @zip # => either 43 or 44, who knows?

这是因为实例变量@zip可以在范围之外访问foo函数,因此两个线程可能同时访问它。

通过在更改变量的代码部分周围仔细放置互斥体(锁),可以解决“两个线程同时更改相同数据”的问题。互斥体must被创造before创建线程,因为在互斥体的情况下,两个线程访问同一个互斥体(根据设计)至关重要,以便知道它是否被锁定。

# somewhere else...
@mutex = Mutex.new
@zip   = 42

def foo
  @mutex.synchronize do
    @foo += 1
  end
end

Thread.new do
  foo
end

foo

puts @zip # => 44, for sure!

如果当执行流程达到Mutex#synchronize行,它尝试锁定互斥锁。如果成功,则进入该块并继续执行。一旦块完成,互斥体将再次解锁。如果互斥量已经被锁定,则线程会等待,直到它再次空闲......实际上,它就像一扇每次只有一个人可以穿过的门。

我希望这能解决问题。

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

多个线程调用同一个函数 的相关文章

  • Objective C 中最好的多线程方法?

    我正在开发一个 iPad 应用程序 目前正在努力寻找多线程的最佳方法 让我用一个简化的例子来说明这一点 我有一个包含 2 个子视图的视图 一个目录选择器和一个包含所选目录中所有图像缩略图的图库 由于 下载 和生成这些缩略图可能需要相当长的时
  • Rails has_many 通过带有附加属性的表单

    我正在尝试创建一个表单 允许用户向活动添加 编辑 删除位置 我目前找到的所有例子要么是HABTM表单 不允许编辑存在于表单中的附加属性 has many through配置 或仅列出现有关系 下面的图片显示了我想要完成的任务 该列表将显示每
  • Shared Web Workers 是否会在单页重新加载、链接导航中持续存在

    共享网络工作者 http www whatwg org specs web apps current work shared workers introduction旨在允许来自同一站点 来源 的多个页面共享单个 Web Worker 但是
  • iOS - 确保在主线程上执行[重复]

    这个问题在这里已经有答案了 我想知道如何打电话给我function on the 主线程 我如何确保我的function被称为主线程 这是继之前的question https stackoverflow com questions 1105
  • C++:Linux平台上的线程同步场景

    我正在为 Linux 平台实现多线程 C 程序 其中我需要类似于 WaitForMultipleObjects 的功能 在搜索解决方案时 我发现有一些文章描述了如何在 Linux 中实现 WaitForMultipleObjects 功能
  • 当你不继承Rails 4中的ApplicationController时,如何包含respond_to?

    我在 Rails 4 1 2 应用程序中有一个 API 控制器 它不继承自应用程序控制器 我试图包含 respond to 方法并得到一个方法未定义的错误 所以然后我需要在顶部的操作包 如下所示 require action pack cl
  • Ruby,通过 SSH 和 LOG 逐一运行 linux 命令

    我想用 Ruby 女巫 net ssh 编写代码 在远程 Linux 机器上一一运行命令并记录所有内容 在 Linux 机器上称为命令 stdout 和 stderr 所以我写函数 def rs ssh cmds cmds each do
  • Webworker-threads:在工作线程中使用“require”可以吗?

    使用 Sails js 我正在测试 webworker threads https www npmjs com package webworker threads https www npmjs com package webworker
  • Ruby on Rails 中的枚举

    我是一名 C 程序员 我正在研究 ruby on Rails 但我可能在心态或其他方面遇到了一些麻烦 我有一个投票对象 该对象可以是赞成 中立或反对 我通常会让投票对象有一个像这样的字段 private VoteEnum voteEnum
  • 如何使用多线程

    我有这个代码 import thread def print out m1 m2 print m1 print m2 print n for num in range 0 10 thread start new thread print o
  • 为什么在 WinForms 中可以跨线程添加控件,而在 WPF 中却不能?

    在虚拟 WinForms 应用程序中 我可以在设计时创建 ListBox 在运行时创建后台线程 然后从后台线程将控件添加到 ListBox 但如果我在 WPF 中执行相同的操作 则会出现错误 为什么我可以在 WinForms 中执行此操作
  • 带有可选第一个哈希参数和keyword_args的奇怪方法行为

    我有以下方法 def test first param nil keyword arg nil puts first param first param puts keyword arg keyword arg end 以下所有调用都按照我
  • 解析包含 json 字符串的 json

    我有一个 json 里面有另一个 json 但它在双引号内 因此它给了我一个解析错误 除了使用之外还有什么方法可以解析这个jsongsub替换双引号 obj Name FirstName Douglas LastName Crockford
  • 同时运行 x 个网络请求

    我们公司有一个网络服务 我想通过我自己的服务发送 XML 文件 存储在我的驱动器上 HTTPWebRequestC 中的客户端 这已经有效了 Web服务同时支持5个同步请求 一旦服务器上的处理完成 我就会从Web服务获得响应 每个请求的处理
  • 直接或通过包含定义嵌套类

    假设我正在为我的家庭存储系统建模 我有很多不同类型的Container 而且我发现其中很多都有装饰品 因此我为这种常见情况设置了一些辅助代码 我的容器中有我的Mantlepiece and my Bookcase 我只在前者上存放装饰品 而
  • 如何在 Rails 3 中连接表并计算记录数?

    我有一个Collection有很多硬币的类 我正在尝试选择拥有两枚以上硬币的收藏品 目前 我可以直接通过 Ruby 来完成此操作 但效率极低 我当前的代码 collections Collection all select c c coin
  • 如何让node.js中的线程休眠而不影响其他线程?

    As per 了解 Node js 事件循环 http blog mixu net 2011 02 01 understanding the node js event loop node js支持单线程模型 这意味着如果我向 Node j
  • 从 Android 函数更新 Textview

    有人可以告诉我如何从函数更新 Android Textview 控件吗 我在互联网上进行了深入搜索 看到很多人都问同样的问题 我测试了线程但无法工作 有人有一个简单的工作示例吗 例如 调用一个函数 在循环中运行多次 并且该函数在 TextV
  • 如何使用define_method创建类方法?

    如果您尝试以元编程方式创建类方法 这非常有用 def self create methods method name To create instance methods define method method name do end T
  • 线程安全的有限大小队列,不使用锁

    我正在尝试编写一个主题队列 但遇到死锁和其他多线程问题 我想用Interlocked CompareExchange避免lock用法 但这段代码并没有按预期工作 它只是擦除整个队列 我在这里做错了什么 public class FixedS

随机推荐

  • 我们如何配置闪亮的开源服务器来支持并发用户

    我有一个 R Shiny 应用程序 我想使用开源解决方案托管该应用程序以支持大约 50 个并发用户 我遇到了 RStudio 的闪亮服务器 它可以用来将闪亮的应用程序部署到网络上 我想使用shinyserver的开源版本 文档说我们可以使用
  • 权限拒绝:编写 com.sec.android.provider.badge.BadgeProvider

    我最近在使用 Android Nougat 的三星手机上运行我的应用程序时发生崩溃 我没有授予 com sec android provider badge BadgeProvider 的运行时权限 这导致了崩溃 我不知道如何授予此徽章提供
  • Printf - 读取位置访问冲突 - C++

    0xC0000005 读取位置 0xcccccccc 时发生访问冲突 printf 抛出此异常 我不知道为什么会发生这种情况 这些字符串变量中有值 我使用 printf 错误吗 帮助 请参阅开关盒 string header string
  • 使用 Tortoise-Hg 克隆在中间中止[命令返回代码 255]

    我在用乌龟汞 http tortoisehg bitbucket io download for 克隆一个叉子 from CodePlex http nearforums codeplex com SourceControl changes
  • 将 Kaggle csv 从下载网址导入到 pandas DataFrame

    我一直在尝试不同的方法来导入 SpaceX 任务csv file https www kaggle com spacex spacex missions downloads database csv on Kaggle https www
  • 无法加载文件或程序集 Microsoft.IdentityModel.Tokens 问题

    我正在尝试使用 JWT 令牌验证用户 我下面使用的代码在控制台应用程序中运行得非常好 但是当我想将它应用到我的 Azure 函数中时 它给出了错误 Could not load file or assembly Microsoft Iden
  • 系统属性管理

    有没有 足够 的方法来更改詹金斯的系统属性 改变它们最简单 最快的方法是什么 例如 我需要关闭无用的 在我的例子中 ping 线程 如果您确实想要一种快速而简单的方法来更改系统属性 您可以使用脚本控制台 https wiki jenkins
  • 参数/模式中“&variable”的含义

    什么是 variable当它用于模式或闭包参数时意味着什么 for code in self exit code iter let mut new seps do seps iter fold result next 这里我们有 code
  • JavaFX 自定义控制器工厂

    我一直在尝试FXMLLoader并使用setControllerFactory使用自定义方法Callback
  • 如何过滤文本框中的自动完成结果

    我为一个网站创建了自动完成 ajax 搜索 该网站自动完成组织名称和地址 但我希望它能够验证 当有人搜索组织名称时 地址文本应该仅给出自动完成结果 匹配搜索组织名称 谁能给我建议吗 ajax 组织地址 addresso GET term q
  • WCF服务参考生成自己的契约接口,不会重用我的

    我的第一个问题希望它合适 共享接口组装 我有一个 共享 程序集 它有一个接口 我们称之为它IDocRepository 它标有 ServiceContract 并且有几个 OperationContract 标记方法 WCF 实现组件 我有
  • 哪些 Java 库可以接受 HTTP 标头解析? [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 哪些 Java 库解析 HTTPAccept header 你应该阅读这篇文章 http www xm
  • React Native - 如何从推送通知打开路线

    我在用着react navigation and react native push notification 我怎样才能打开某个StackNavigator s屏幕输入onNotification打回来 应该在以下情况下工作 应用程序已关
  • 是否可以使用 Facebook API + PHP 从我拥有的封闭群组中获取 Facebook 提要、点赞和评论

    我想构建一个 Web 应用程序 使用 Facebook API PHP 从我拥有的封闭群组获取提要 点赞和评论 我看到我可以使用这个 Graph API 接口获取信息 开始阅读 facebook 文档 并开始思考我实际上不能这样做 http
  • HttpWebRequest 中“无法连接到远程服务器失败”

    我正在使用 VSTS 2008 C Net 3 5 开发控制台应用程序 并将请求发送到另一台服务器 Windows Server 2008 上的 IIS 7 0 我发现当请求线程数很大 例如 2000 个线程 时 客户端在调用 respon
  • 核心数据独特属性

    是否可以使 Core Data 属性唯一 即两个 MyEntity 对象不能具有相同的 myAttribute 我知道如何以编程方式强制执行此操作 但我希望有一种方法可以使用 xcode 中的图形数据模型编辑器来执行此操作 我正在使用 iP
  • Rails 3 中的多级嵌套布局

    我有一个带有全局应用程序布局文件的应用程序application html haml 然后 我有多个 控制器堆栈 用于我们的主站点 我们的管理门户和我们的业务站点 对于其中每一个 控制器都位于一个模块内 并且都继承自同一个模块BaseCon
  • java.io.FileNotFoundException:(权限被拒绝)

    我想读取 Vista 上我的文档文件夹中的文件 该字段确实存在于指定位置 但在尝试打开文件的输入流时仍然收到以下错误 java io FileNotFoundException Permission denied at java io Fi
  • Angular 2嵌套路由解析执行

    例如 如果我有以下路线组织 const appRoutes Routes path component AppComponent resolve app AppResolver children path component NestedC
  • 多个线程调用同一个函数

    假设我们有多个线程都调用同一个函数 def foo do stuff end 100 times do i Thread new do foo end end 如果当前有两个或多个线程foo 它们是否共享相同的局部变量foo 这涉及到我的第