Home  >  Article  >  Backend Development  >  How to resolve deadlock (waiting for signal of failed test)

How to resolve deadlock (waiting for signal of failed test)

王林
王林forward
2024-02-08 23:33:19670browse

How to resolve deadlock (waiting for signal of failed test)

php editor Xiaoxin will introduce to you how to solve the deadlock problem. Deadlock is a common problem in concurrent programming. Deadlock occurs when two or more processes wait for each other to release resources. In order to solve this problem, we can use some common methods, such as using mutex locks, avoiding resource competition, using timeout mechanisms, etc. Through reasonable design and adjustment, we can effectively avoid the occurrence of deadlock and improve the concurrency and stability of the program. Next, let’s take a closer look at how to solve the deadlock problem!

Question content

I have two goroutines, which are two testxxx functions during testing. I use condition variables to synchronize these goroutines. However, once one of the tests fails, the other one is waiting for a signal. The deadlock is coming. Also, if testfunctionb fails, I want testfunctiona to fail too.

var cond sync.cond
func testfunctiona(t *testing.t){
   // ... some codes...
   cond.wait()
}
func testfunctionb(t *testing.t){
   // ... some codes...
   t.fail()
   // ... some codes...
   cond.broadcast()
}

I have tried some methods, such as:

var cond sync.Cond
var A_t *testing.T
func TestFunctionA(t *testing.T){
   // ... Some codes...
   A_t = t
   // ... Some codes...
   cond.Wait()
}
func TestFunctionB(t *testing.T){
   // ... Some codes...
   t.Cleanup(func(){
      if !A_t.Failed(){
          A_t.Fail()
      }
      cond.Broadcast()
   })
   t.Fail()
   // ... Some codes...
   cond.Broadcast()
}

But when functionb has no errors, a_t.fail() will still be triggered.

I am also considering using context.context(). However, I don't know how to run the test function within the context. Thank you for reading my question! I appreciate any comments or discussion!

Workaround

One test should not interact with another test. However, when using subtests we can share anything between test cases.

Here is an example:

package main

import (
    "errors"
    "testing"
)

func TestFruits(t *testing.T) {
    var err error
    t.Run("test apple", getTestAppleFunc(&err))
    t.Run("test banana", getTestBananaFunc(&err))
}

func handleError(t *testing.T, err *error) {
    if err != nil && *err != nil {
        t.Error(*err)
    }
}

func getTestAppleFunc(err *error) func(*testing.T) {
    return func(t *testing.T) {
        handleError(t, err)
        *err = errors.New("Apple failed")
    }
}

func getTestBananaFunc(err *error) func(*testing.T) {
    return func(t *testing.T) {
        handleError(t, err)
    }
}
  • In the functions gettestbananafunc and gettestapplefunc, the error pointer is passed as a parameter.
  • In the above example, the first execution is gettestapplefunc.
  • If there is an incorrect assignment in gettestapplefunc (as in the example above), the gettestbananafunc function will fail.

The above is the detailed content of How to resolve deadlock (waiting for signal of failed test). For more information, please follow other related articles on the PHP Chinese website!

Statement:
This article is reproduced at:stackoverflow.com. If there is any infringement, please contact admin@php.cn delete