如何更改 goroutine 闭包内的外部变量的值

2024-01-06

func (this *l) PostUpload(ctx *Context) {

    //ctx.Response.Status = 500

    l, err := models.NewL(this.Config)
    go func() {
        err = l.Save(file) 
        if err != nil {
            ctx.Response.Status = 500
            ctx.Response.Body = err
        } else {
            ctx.Response.Status = 204
        }
    }()
}

如何改变ctx.Response.Statusgoroutine 闭包内的值?


您无法保证观察到另一个 goroutine 中变量值的更改不同步. See Go 内存模型 https://golang.org/ref/mem了解详情。

所以如果你想改变ctx.Response.Status在另一个 Goroutine 中,为了保证此更改在调用者 Goroutine 中可见,请使用同步。

有多个同步原语。您可以使用频道或sync http://golang.org/pkg/sync/包裹。

使用渠道:

ch := make(chan int)

go func() {
    err = l.Save(file) 
    if err != nil {
        ctx.Response.Status = 500
        ctx.Response.Body = err
    } else {
        ctx.Response.Status = 204
    }
    ch <- 0 // Signal that ctx is updated
    // goroutine may do other works (not related to changing ctx)
}()

<- ch // Wait for the goroutine to finish updating ctx

Using sync.WaitGroup http://golang.org/pkg/sync/#WaitGroup:

var wg sync.WaitGroup
wg.Add(1)

go func() {
    err = l.Save(file) 
    if err != nil {
        ctx.Response.Status = 500
        ctx.Response.Body = err
    } else {
        ctx.Response.Status = 204
    }
    wg.Done() // Signal that ctx is updated
    // goroutine may do other works (not related to changing ctx)
}()

wg.Wait() // Wait for the goroutine to finish updating ctx

Using sync.Mutex http://golang.org/pkg/sync/#Mutex:

m := sync.Mutex{}
m.Lock()

go func() {
    err = l.Save(file) 
    if err != nil {
        ctx.Response.Status = 500
        ctx.Response.Body = err
    } else {
        ctx.Response.Status = 204
    }
    m.Unlock() // Signal that ctx is updated
    // goroutine may do other works (not related to changing ctx)
}()

m.Lock() // Wait for the goroutine to finish updating ctx

Note:

最好使用以下命令来表示完成(在您的情况下为 ctx 更新)defer这样,如果启动的 goroutine 以某种意外的方式结束(例如运行时恐慌),调用者 goroutine 不会永远被阻塞。但请注意,在这种情况下,完成信号只会在匿名函数末尾发送(即执行延迟函数时)。

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

如何更改 goroutine 闭包内的外部变量的值 的相关文章

  • Go API 在 html 中显示 swagger api 规范 (json) (Swagger UI)

    我有一个服务于特定端口的应用程序 gorilla mux 我也有一个 json 文件形式的 swagger API 规范 是否有任何 go API 可以像 spring boot 一样从 JSON 文件生成 swagger UI 定义 我正
  • Go SQL查询不一致

    我在执行查询时遇到一些非常奇怪的不一致 并且想知道是否有人知道原因 想象一下我有一个定义如下的结构 type Result struct Afield string db A Bfield interface db B Cfield str
  • 我应该在请求中创建 executorService 还是在 Web 应用程序中共享一个实例?

    我正在向基于 Jersey 的 Web 服务添加一个新端点 支持端点的逻辑需要对另一个服务进行 10 到 50 次调用 这些调用是独立的并且可以并行化 因此我正在考虑使用执行器服务将工作分配到多个线程 我想知道是否应该为每个请求实例化一个
  • 如何在 Go 中表示可选字符串?

    我希望建模一个可以有两种可能形式的值 不存在或字符串 执行此操作的自然方法是Maybe String or Optional
  • 取消用户特定的 goroutine [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 我有一个应用程序 网络应用程序 允许用户使用 twitter oauth 登录并提供自动推文删除功能 用户登录到 Web 应用程序后
  • 给定方法值,获取接收者对象

    Go 有没有办法从方法值获取接收者对象 例如有没有这样的MagicFunc这将使以下程序输出字符串my info来自底层 Foo 实例 package main import fmt type Foo struct A string fun
  • 即使没有显式事务,SQL Server 也会获取锁吗?

    我第一次阅读有关 MSSQL 锁定的内容 在很多地方 锁定机制概念依赖于事务的存在 我想知道在不涉及任何事务的情况下是否可以锁定 一般来说 当不存在显式事务时 每个 SQL 语句都在自动 自动提交 事务中执行 在这种情况下将应用正常的锁定行
  • 无法连接到代理“证书由未知机构签名”

    我正在尝试通过 Kubernetes 部署上的 cloudsql proxy 容器连接到 CloudSQL 实例 我已安装 cloudsql 凭据以及值GOOGLE APPLICATION CREDENTIALS set 但是 我的日志中仍
  • Golang 按位运算以及一般字节操作

    我有一些 C 代码 可以对字节执行一些按位运算 我正在尝试在 golang 中做同样的事情 但遇到了困难 C 中的示例 byte a c byte data int j c data j c byte c j c a c 0xFF c 0x
  • 何时在多线程中使用 易失性?

    如果有两个线程访问全局变量 那么许多教程都说使该变量成为易失性的 以防止编译器将变量缓存在寄存器中 从而无法正确更新 然而 两个线程都访问共享变量需要通过互斥体进行保护 不是吗 但在这种情况下 在线程锁定和释放互斥体之间 代码位于关键部分
  • 无法通过键获取 Gorilla 会话值

    我无法通过这种方式从会话中获取价值 它是nil session initSession r valWithOutType session Values key 完整代码 package main import fmt github com
  • 在使用 stop_token 等待条件变量_any 时是否需要拥有锁来请求停止?

    在等待条件变量时 更改谓词状态的线程必须拥有锁 因此在唤醒期间不会错过更新 根据文档 这是必要的 即使在使用原子变量时也是如此 不过我不确定是否request stop 已经正确处理了 那么问题是 这两个选项中哪一个是正确且符合标准的呢 j
  • 在golang中获取TTFB(第一个字节的时间)值

    我正在尝试获取 TTFB 值和 Connect 值 c exec Command curl w Connect time connect TTFB time starttransfer Total time time total o dev
  • Go 无法推断赋值中的类型:“non-name on left side of :=”

    该片段按预期工作play golang org p VuCl OKMav http play golang org p VuCl OKMav i 10 next 11 prev i i next 然而这个几乎相同的片段给出了non name
  • 如何从非英语字符串解析go中的月份

    我想将以下字符串解析为 go 中的日期 This item will be released on March 9 2014 我跟着this https stackoverflow com questions 14106541 go par
  • Haskell 排列库函数 - 请澄清一下?

    这是代码permutationsHaskell 中的函数Data List module permutations a gt a permutations xs0 xs0 perms xs0 where perms perms t ts i
  • 为什么 Go 中只有 int 而没有 float?

    在 Go 中 有这样的类型int这可能相当于int32 or int64取决于系统架构 我可以声明一个整数变量而不用担心它的大小 var x int 为什么没有这个类型float 这相当于float32 or float64取决于我的系统架
  • 为什么 i++ 不是原子的?

    Why is i Java 中不是原子的 为了更深入地了解 Java 我尝试计算线程中循环的执行频率 所以我用了一个 private static int total 0 在主课中 我有两个线程 主题 1 打印System out prin
  • 如何在Go中将字节数组转换为字符串[重复]

    这个问题在这里已经有答案了 byte字符串会引发错误 string byte n 也会引发错误 顺便说一下 例如 文件名的 sha1 值是字符串 它是否明确需要 utf 8 或任何其他编码集 谢谢 我用来转换的最简单方法byte to st
  • Java:使用 Java.util.concurrent 线程访问读取线程串行端口

    我正在尝试编写一个 Java 串行设备驱动程序并想使用 对我来说是新的 java util concurrent包裹 我有一种发送数据包然后等待 ACK 的方法 我打算有炭 接收在不同的线程中运行 如果接收线程收到 ACK 它应该使用发送数

随机推荐

  • 模态窗口和对话窗口有什么区别?

    这个问题准确地描述了我想知道的内容 模态窗口和对话有什么区别 当模式窗口变成对话时 反之亦然 我该如何实现这两个目标 非常感谢朝正确方向的推动 模态窗口是在应用程序之上运行的窗口 因此在关闭模态窗口之前您无法对应用程序执行任何操作 jQue
  • Laravel - 将 PHP 资源传递给 Storage::put

    Laravel 文档 https laravel com docs 5 2 filesystem storing files https laravel com docs 5 2 filesystem storing files 说明这一点
  • Swift 中两个弱变量相互引用?

    今天我再次尝试理解 Swift 中的保留循环和弱引用 阅读通过文档 https developer apple com library ios documentation Swift Conceptual Swift Programming
  • 可视化解决方案资源管理器中的实际文件夹?

    MS Visual Studio 有解决方案资源管理器 我可以在其中查看所有项目文件 我还可以创建类似于文件文件夹的过滤器 以将它们分组 问题是 我希望我的文件在磁盘上的视觉和物理上分组 但我不想在视觉和磁盘上应用每个更改两次 有没有什么方
  • Go中的PostgreSQL列表参数(使用数据库/SQL和pq)

    我正在尝试编写一个采用列表参数 即作为值列表的单个参数 的查询 看来这在 PostgreSQL 中至少有时是可能的 https stackoverflow com a 10829760 836390 https stackoverflow
  • Swing 组件何时“可显示”?

    有没有办法 例如 通过事件 来确定 Swing 组件何时变为 可显示 根据 JavadocsComponent getGraphics http java sun com j2se 1 5 0 docs api java awt Compo
  • HttpClient - 处理聚合异常

    您好 我正在使用与此类似的 HttpClient public static Task
  • github 上的 Teamcity 构建徽章

    我想在我的 github 页面上添加 teamcity 构建徽章 我的存储库是私有 github 存储库 我首先将下面的代码包含为link https blog jetbrains com teamcity 2012 07 teamcity
  • 定义实体框架 1:1 关联

    我试图在实体框架模型中定义两个实体之间的 1 1 关联 一个映射到表 另一个映射到视图 使用 DefinedQuery 当尝试在设计器中定义映射时 它让我选择 1 表或视图来映射关联 我应该选择什么 我可以选择两个表中的任何一个 但随后我被
  • 更新 Ruby on Rails 控制器中的参数

    我有一个控制器 我想在更新之前更新其中一个参数的值 以便在同一个保存到数据库的操作中进行更新 不幸的是 下面的代码没有设置z在数据库中 if model x YES model z blank model params z Time now
  • 如何在Eclipse的“运行配置”中设置“主类”

    在一个Java项目中 有两个java文件都有main方法 这两个java文件的绝对路径是 C Desktop project1 src com pre moveposition1 java And C Desktop project1 sr
  • TypeError:TextIOWrapper 类型的对象不可 JSON 序列化

    如果代码正常工作 那么每当有人在聊天中输入内容时 他们都会获得 5 经验 并且该信息会被放入 json文件 但发生的情况是每当有人在聊天中输入内容时就会出现此错误 on message users json dumps f TypeErro
  • Visual Studio Code 语言扩展继承现有的

    在 Visual Studio Code 中 只需提供语法文件即可添加自己的语言扩展 例如通过 JSON 我想为我使用的特定脚本语言提供语法文件 脚本语言嵌入在 ARM 汇编源代码中 并且已经存在一个插件 所以我基本上想通过我的脚本语言来扩
  • Log4j 1:如何在不更新版本到2.15.0的情况下缓解Log4j中的漏洞

    我正在使用 Log4j 1 2 16 我将其与 Maven 一起使用Selenium https en wikipedia org wiki Selenium 28software 29测试Java项目 我正在寻找一种无需升级Log4j版本
  • 创建动态 php 插入 mysql 函数?

    我有一篇包含很多变量的帖子 我想知道是否有某种方法可以动态地将信息插入到 mysql 中 而不是手动全部输入 因为帖子变量会根据用户选择的内容而变化 这就是我们用来做类似事情的方法 插入到我们无法控制的表中 并且没有 API 访问权限 使用
  • 如何在使用 Core Graphics 绘制的图像上设置辅助功能标签?

    我正在尝试围绕一些核心图形逻辑编写 UIAutomation 测试 目前我们正在使用核心图形来绘制图像 我正在尝试在图像上设置可访问性标签 标识符 值 以便我可以通过 UIAutomation 测试验证其存在 但无论我做什么 我都无法在 D
  • ListFragment 未渲染且适配器中的 getView() 未被调用

    据我所知 这可能是因为我的 ListView 没有显示 我已经验证 getCount 返回的值不为零 但我看不出我做错了什么 一切都加载并表现得好像它正在工作 但 ListView 从未出现 我在 mix xml 中的片段引用上放置了背景颜
  • 如何选择特定客户?

    我创建了以下表格 create table customers ID varchar 9 name varchar 15 CONSTRAINT pk id PRIMARY KEY ID create table living places
  • GMail 似乎忽略回复

    我正在使用 Gmail 帐户从我的网站发送电子邮件 我使用同一帐户来接收由我网站上的联系工具生成的电子邮件 我使用 回复 字段是为了更轻松地回复并轻松回复人们 该消息带有 发件人 地址 并忽略 回复 地址 这是我的标题 Return Pat
  • 如何更改 goroutine 闭包内的外部变量的值

    func this l PostUpload ctx Context ctx Response Status 500 l err models NewL this Config go func err l Save file if err