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
}
}()
}
如何更改goroutine闭包内的ctx.Response.Status
值?
答案 0 :(得分:2)
您无法保证在没有同步的情况下观察另一个goroutine 中变量值的更改。有关详细信息,请参阅The Go Memory Model。
因此,如果您想在另一个goroutine中更改<ion-scroll direction="x" class="item row" id="galleryline1">
<div class="first_row" id="firstrow">
<div>
<img ng-repeat="image in allimages" ng-src="{{image.src}}" ng-click="showImages(image.title)" class="image-list-thumb"/>
</div>
</div>
</ion-scroll>
,则可以保证在调用者goroutine使用同步中可以看到此更改。
有多个同步原语。您可以使用频道或sync
包。
ctx.Response.Status
sync.WaitGroup
: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
sync.Mutex
: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
注意:强>
优良作法是使用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
发出完成信号(在您的情况下为ctx更新),以便如果启动的goroutine以某种意外的方式结束(例如运行时恐慌),则调用者goroutine将不会永远被阻止。但请注意,在这种情况下,完成信号将仅在匿名函数结束时发送(即执行延迟函数时)。