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.Status
goroutine 闭包内的值?
您无法保证观察到另一个 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(使用前将#替换为@)