Go 如何给某个协程加锁(不允许开新的协程)
问题描述
1.可能我的题目描述的不太清除,这里详细描述一下
项目是用 beego 开发的,其中在控制器中又一个方法
//同步图片
func (this *ApiController) SyncImages() {
.
.
.
go models.TestSyncImages(images)
.
.
.
}
在另外一个 models
包里面有上述协程调用的方法
func TestSyncImages(list []SyncImage) {
var image = auxpi.Image{}
var wg sync.WaitGroup
for _, value := range list {
go func(url string, id uint) {
wg.Add(1)
defer wg.Done()
res, _ := http.Get(url)
lUrl, name, del := localStoreInfo(res.Header.Get("Content-Type"), url)
dst, _ := os.Create(name)
io.Copy(dst, res.Body)
image.ID = id
image.Url = lUrl
image.Delete = del
AddSyncImage(image)
}(value.External, value.ImageID)
}
wg.Wait()
}
工作流程是:
用户提交同步图片
的命令->控制器接到数据 SyncImages()
方法->SyncImages()
启用协程去执行 TestSyncImages()
方法
但是现在出了一个问题,如果用户同时点击两次甚至多次,会出现重复进入TestSyncImages()
,会扰乱当前所在的工作的协程,如果点击多次甚至会出现内存溢出的状况。
请问各位,如何保证 TestSyncImages()
这个方法不会被多次执行,有什么办法给这个东西加锁,或者使用别的更好的方法解决?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
这种我建议你在SyncImages方法中按照
用户ID
加缓存判断,比如1分钟只能点一次,那点击的时候检测有没有这个缓存,如果有,则不同步,如果没有则写入缓存后同步我想你需要的是单例模式。看一下这篇文章。
如果是个单机程序,推荐使用 sync.Once, 如果是分布式服务器上,推荐使用 redis 的 setnx 指令,加一个锁。可以百度搜索下,参考下 https://www.jianshu.com/p/c97... 这种类似的文章