我想编写一个恢复goroutine painc的函数,下面的演示为“test1”恢复了goroutine painc,但不支持“test2”,“test3”,“test4”。
我怎样才能编写一个函数来恢复任何goroutine痛苦。
func main() {
go myGoroutine(test1)
time.Sleep(10 * time.Second)
}
func myGoroutine(realGoFunc func()) {
defer func() {
if err := recover(); err != nil {
fmt.Println(err)
}
}
realGoFunc()
}
func test1() {
fmt.Println("test1 come here)
painc("test1 error")
fmt.Println("test1 end")
}
func test2(username string) {
fmt.Println("test2 come here)
painc("test2 error")
fmt.Println("test2 end")
}
func test3(userId int64, username string) {
fmt.Println("test3 come here)
painc("test3 error")
fmt.Println("test3 end")
}
func test4(user *User) {
fmt.Println("test4 come here)
painc("test4 error")
fmt.Println("test4 end")
}
最佳答案
在您的情况下,可能(但不太好)选择使用上下文:
type User struct {
name string
uid int64
}
func main() {
user := &User{
name: "hezhixiong",
uid: int64(58741634),
}
ctx := context.WithValue(context.Background(), "name", user.name)
ctx = context.WithValue(ctx, "uid", user.uid)
ctx = context.WithValue(ctx, "user", user)
go SafeFunc(test1, ctx)
go SafeFunc(test2, ctx)
go SafeFunc(test3, ctx)
go SafeFunc(test4, ctx)
for {
}
}
func test1(ctx context.Context) {
panic("test1")
}
func test2(ctx context.Context) {
name := ctx.Value("name").(string)
panic(name)
}
func test3(ctx context.Context) {
name := ctx.Value("name").(string)
uid := ctx.Value("uid").(int64)
panic(fmt.Sprintln(name, uid))
}
func test4(ctx context.Context) {
user := ctx.Value("user").(*User)
panic(user)
}
// SafeFunc safe function call
func SafeFunc(f func(context.Context), ctx context.Context) {
defer func() {
if r := recover(); r != nil {
fmt.Println(r)
}
}()
f(ctx)
}
在生产中,通常会像这样扭曲输入和输出:
func test(in *input) (out *output) {
// parse in
// ... do something
// build out
}
关于go - 重写goroutine函数并进行恢复,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58741634/