github.com/gogf/gf@v1.16.9/.example/os/gmlock/4.test_deadlock.go (about)

     1  package main
     2  
     3  import (
     4  	"fmt"
     5  	"math/rand"
     6  	"sync"
     7  	"time"
     8  
     9  	"github.com/gogf/gf/os/gmlock"
    10  )
    11  
    12  // 测试Locker是否会产生死锁
    13  func main() {
    14  	var (
    15  		l      = gmlock.New()
    16  		wg     = sync.WaitGroup{}
    17  		key    = "test"
    18  		event  = make(chan int)
    19  		number = 100000
    20  	)
    21  	for i := 0; i < number; i++ {
    22  		wg.Add(1)
    23  		go func() {
    24  			<-event
    25  			l.Lock(key)
    26  			//fmt.Println("get lock")
    27  			l.Unlock(key)
    28  			wg.Done()
    29  		}()
    30  	}
    31  
    32  	for i := 0; i < number; i++ {
    33  		wg.Add(1)
    34  		go func() {
    35  			<-event
    36  			l.RLock(key)
    37  			//fmt.Println("get rlock")
    38  			l.RUnlock(key)
    39  			wg.Done()
    40  		}()
    41  	}
    42  
    43  	for i := 0; i < number; i++ {
    44  		wg.Add(1)
    45  		go func() {
    46  			<-event
    47  			if l.TryLock(key) {
    48  				//fmt.Println("get lock")
    49  				l.Unlock(key)
    50  			}
    51  			wg.Done()
    52  		}()
    53  	}
    54  
    55  	for i := 0; i < number; i++ {
    56  		wg.Add(1)
    57  		go func() {
    58  			<-event
    59  			if l.TryRLock(key) {
    60  				//fmt.Println("get rlock")
    61  				l.RUnlock(key)
    62  			}
    63  			wg.Done()
    64  		}()
    65  	}
    66  
    67  	for i := 0; i < number; i++ {
    68  		wg.Add(1)
    69  		go func() {
    70  			<-event
    71  			if l.TryLock(key) {
    72  				// 模拟业务逻辑的随机处理间隔
    73  				time.Sleep(time.Duration(rand.Intn(100)) * time.Millisecond)
    74  				l.Unlock(key)
    75  			}
    76  			wg.Done()
    77  		}()
    78  	}
    79  
    80  	for i := 0; i < number; i++ {
    81  		wg.Add(1)
    82  		go func() {
    83  			<-event
    84  			if l.TryRLock(key) {
    85  				// 模拟业务逻辑的随机处理间隔
    86  				time.Sleep(time.Duration(rand.Intn(100)) * time.Millisecond)
    87  				l.RUnlock(key)
    88  			}
    89  			wg.Done()
    90  		}()
    91  	}
    92  	// 使用chan作为事件发送测试指令,让所有的goroutine同时执行
    93  	close(event)
    94  	wg.Wait()
    95  
    96  	fmt.Println("done!")
    97  }