In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-01-18 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Internet Technology >
Share
Shulou(Shulou.com)06/01 Report--
In order to solve this problem, this article introduces the corresponding analysis and solution in detail, hoping to help more partners who want to solve this problem to find a more simple and feasible method.
Introduction
In the Goto language, we usually use panic and recover to throw and catch errors. This pair of operations can be used normally in a single co-programming environment without stepping on any holes. However, in the multi-process concurrent environment, we often encounter the following two problems. Suppose we have two cooperators now. Let's call them Synergy An and B.
If panic occurs in Program A, will Program B die because of its panic?
If panic occurs in co-program A, can co-program B capture the panic of co-program A with recover?
The answers are: yes and no.
So let's verify them one by one and give best practices in specific business scenarios.
Question one
If panic occurs in Program A, will Program B die because of its panic?
To verify this problem, let's write a program:
Package mainimport ("fmt"time") func main () {/ / for {fmt.Println ("goroutine1_print")}} () / / Bgo func () {time.Sleep (1 * time.Second) panic ("goroutine2_panic")} () time.Sleep (2 * time.Second)}
First of all, the main cooperative program opens the two subprograms An and BMaga to print the goroutine1_print string in a loop; after sleeping for 1 second, the B program will throw panic (sleep this step is to ensure that after A starts to print), the master program sleeps for 2 seconds, waiting for the An and B subprograms to complete execution, and the main program exits. The final print result is as follows:
.. goroutine1_printgoroutine1_printgoroutine1_printgoroutine1_printgoroutine1_printgoroutine1_printgoroutine1_printgoroutine1_printgoroutine1_printgoroutine1_printgoroutine1_printgoroutine1_printpanic: goroutine2_panicgoroutine1_printgoroutine1_printgoroutine goroutine1_print19goroutine1_printgoroutine1_printgoroutine1_printgoroutine1_print [runninggoroutine1_print]: goroutine1_printgoroutine1_printgoroutine1_printmain.main.func2 () / Users/jiangbaiyan/go/src/awesomeProject/main.go:18 + 0x46created by main.main / Users/jiangbaiyan/go/src/awesomeProject/main.go:16 + 0x4d
We can see that before panic occurs in program B, program A prints strings all the time; then programs An and panic print strings alternately, and finally the main program and programs An and B all exit. So we can see that after a panic, it will cause all the programs to die, and the program will exit as a whole. Here we verify the answer to the first question.
As for the reason why panic and co-program A print alternately, it may be because panic also needs to print strings. Because printing also takes time, when we execute the panic line of code, it will take a certain amount of time (although this time is very short) for panic to actually trigger all the programs to die, so in this short period of time, we will see the phenomenon of alternating printing.
Question two
If panic occurs in process A, can other programs capture the panic of Program A with recover?
It's still similar to the above code, and we can simplify it a little bit:
Package mainimport ("fmt"time") func main () {defer func () {if e: = recover (); e! = nil {fmt.Println ("recover_panic")}} () go func () {panic ("goroutine2_panic")} () time.Sleep (2 * time.Second)}
We only started one collaboration program this time, and added recover to the main collaboration program in the hope that it can capture the panic in the sub-collaboration program, but the result failed:
Panic: goroutine2_panicgoroutine 6 [running]: main.main.func2 () / Users/jiangbaiyan/go/src/awesomeProject/main.go:17 + 0x39created by main.main / Users/jiangbaiyan/go/src/awesomeProject/main.go:16 + 0x57Process finished with exit code 2
As we can see, recover does not work. So, where the panic occurs, we need to recover it, and we change it like this:
Package mainimport ("fmt"time") func main () {go func () {defer func () {if e: = recover (); e! = nil {fmt.Println ("recover_panic")}} () panic ("goroutine2_panic")} () time.Sleep (2 * time.Second)}
As a result, the recover_panic string is printed successfully:
Recover_panicProcess finished with exit code 0
So our answer has also been verified: co-program A panic occurs, co-program B can not recover to the panic of co-program A, and only the recover within the co-program itself can capture the panic thrown by itself.
Best practic
Let's assume that there is a scenario where we want to develop a client that calls two services, which do not have any sequential dependencies, so we can open two goroutine to achieve performance improvement by calling the two services concurrently. Well, at this time, the problem we just talked about became a problem.
Generally speaking, what should we do when we don't want one service call to fail and the other service call to fail, but to continue to execute several other service invocation logic?
If you are smart, you will think that if I write a recover statement inside each co-program and let him catch the panic that may occur in each co-program, I will be able to solve the problem that a co-program panic will lead to the failure of all co-programs. We write the following code, which is the best practice for solving problem one in combination with problem two in business development:
/ / invoke the service concurrently Each handler passes in a call logic function func GoroutineNotPanic (handlers... func () error) (err error) {var wg sync.WaitGroup// suppose we want to call so many handlers services for _ F: = range handlers {wg.Add (1) / / each function starts a co-program go func (handler func () error) {defer func () {/ / each co-program uses recover to capture panicif e: = recover () that may occur in the calling logic. E! = nil {/ / A service invocation protocol reports an error. You can print some error logs} wg.Done ()} () / / take the handler calling logic of the first error report. And finally return e: = handler () if err = = nil & & e! = nil {err = e} (f)} wg.Wait () return}
Example of the above method call:
/ / call example func main () {/ / call logic 1aRpc: = func () error {panic ("rpc logic A panic") return nil} / / call logic 2bRpc: = func () error {fmt.Println ("rpc logic B") return nil} err: = GoroutineNotPanic (aRpc, bRpc) if err! = nil {fmt.Println (err)}}
In this way, we have implemented a general concurrent processing logic, we only need to pass in the functions of the business logic for each call, and we do not have to write a set of concurrency control logic separately each time; at the same time, calling logic 2 will not fail because of calling the panic of logic 1, and the fault tolerance rate is higher.
What is gogo is the abbreviation of golang? golang is a static strongly typed, compiled, concurrent and garbage-collected programming language developed by Google. Its syntax is similar to C language, but it does not include functions such as enumeration, exception handling, inheritance, generics, assertions, virtual functions and so on.
This is the answer to the question about error handling in Go multi-process concurrent environment. I hope the above content can be of some help to you. If you still have a lot of doubts to be solved, you can follow the industry information channel for more related knowledge.
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.