英文:
How to prevent deadlock when change map data
问题
我尝试编写一个验证数据的函数。请看下面的代码:
func Create(name, email, password, local string, termOf bool) map[string]string {
wait := new(sync.WaitGroup)
mutex := new(sync.Mutex)
errMsg := make(map[string]string)
if !termOf {
mutex.Lock()
errMsg["termOf"] = translate(local, "text06")
mutex.Unlock()
}
wait.Add(1)
go func() {
err := ValidateName(name, local)
mutex.Lock()
errMsg["name"] = err.Error()
mutex.Unlock()
wait.Done()
}()
wait.Add(1)
go func() {
err := ValidateEmail(email, local)
mutex.Lock()
errMsg["email"] = err.Error()
mutex.Unlock()
wait.Done()
}()
wait.Add(1)
go func() {
err := ValidatePassword(password, local)
mutex.Lock()
errMsg["password"] = err.Error()
mutex.Unlock()
wait.Done()
}()
wait.Wait()
// 如果出现错误
if len(errMsg) > 0 {
return errMsg
}
return nil
}
正如你在这里看到的,我使用了三个 goroutine,在 goroutine 中我锁定它以更改 errMsg 变量的 map 类型。当我运行该函数时,我得到了编译器错误:
runtime error: invalid memory address or nil pointer dereference
[signal 0xc0000005 code=0x0 addr=0x14 pc=0x44206a]
但是当我在 goroutine 中删除所有的 errMsg 插入时,函数就可以正常工作。我不知道我做错了什么原因。
英文:
I try to write a function that validate data. Look at the following code:
func Create(name, email, password, local string, termOf bool) map[string]string {
wait := new(sync.WaitGroup)
mutex := new(sync.Mutex)
errMsg := make(map[string]string)
if !termOf {
mutex.Lock()
errMsg["termOf"] = translate(local, "text06")
mutex.Unlock()
}
wait.Add(1)
go func() {
err := ValidateName(name, local)
mutex.Lock()
errMsg["name"] = err.Error()
mutex.Unlock()
wait.Done()
}()
wait.Add(1)
go func() {
err := ValidateEmail(email, local)
mutex.Lock()
errMsg["email"] = err.Error()
mutex.Unlock()
wait.Done()
}()
wait.Add(1)
go func() {
err := ValidatePassword(password, local)
mutex.Lock()
errMsg["password"] = err.Error()
mutex.Unlock()
wait.Done()
}()
wait.Wait()
// If errors appear
if len(errMsg) > 0 {
return errMsg
}
return nil
}
As you can see here, I use three goroutines and in the goroutine I lock it to change errMsg variable map type. When I run the function, I've got compiler error
runtime error: invalid memory address or nil pointer dereference
[signal 0xc0000005 code=0x0 addr=0x14 pc=0x44206a]
But when I remove in the goroutine all errMsg inserts, then the function works. I do not know the reason what I do wrong.
答案1
得分: 3
从ValidateName()
、ValidateEmail()
或ValidatePassword()
调用返回时,err
可能是nil
。
在将其添加到映射之前,应检查err != nil
。
if err != nil {
mutex.Lock()
errMsg["xxx"] = err.Error()
mutex.Unlock()
}
换句话说,问题不在于映射errMsg
,而在于您想要放入其中的值。
英文:
It is possible that err
is nil
when returning from ValidateName()
, ValidateEmail()
or ValidatePassword()
calls.
You should check err != nil
before adding it to the map.
if err != nil {
mutex.Lock()
errMsg["xxx"] = err.Error()
mutex.Unlock()
}
In other words, this isn't the map errMsg
which is the issue, but the value you want to put in it.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论