github.com/wangyougui/gf/v2@v2.6.5/os/gmlock/gmlock_z_unit_test.go (about)

     1  // Copyright GoFrame Author(https://goframe.org). All Rights Reserved.
     2  //
     3  // This Source Code Form is subject to the terms of the MIT License.
     4  // If a copy of the MIT was not distributed with this file,
     5  // You can obtain one at https://github.com/wangyougui/gf.
     6  
     7  package gmlock_test
     8  
     9  import (
    10  	"sync"
    11  	"testing"
    12  	"time"
    13  
    14  	"github.com/wangyougui/gf/v2/container/garray"
    15  	"github.com/wangyougui/gf/v2/os/gmlock"
    16  	"github.com/wangyougui/gf/v2/test/gtest"
    17  )
    18  
    19  func Test_Locker_Lock(t *testing.T) {
    20  	gtest.C(t, func(t *gtest.T) {
    21  		key := "testLock"
    22  		array := garray.New(true)
    23  		go func() {
    24  			gmlock.Lock(key)
    25  			array.Append(1)
    26  			time.Sleep(300 * time.Millisecond)
    27  			gmlock.Unlock(key)
    28  		}()
    29  		go func() {
    30  			time.Sleep(100 * time.Millisecond)
    31  			gmlock.Lock(key)
    32  			array.Append(1)
    33  			gmlock.Unlock(key)
    34  		}()
    35  		time.Sleep(100 * time.Millisecond)
    36  		t.Assert(array.Len(), 1)
    37  		time.Sleep(100 * time.Millisecond)
    38  		t.Assert(array.Len(), 1)
    39  		time.Sleep(200 * time.Millisecond)
    40  		t.Assert(array.Len(), 2)
    41  		gmlock.Remove(key)
    42  	})
    43  
    44  	gtest.C(t, func(t *gtest.T) {
    45  		key := "testLock"
    46  		array := garray.New(true)
    47  		lock := gmlock.New()
    48  		go func() {
    49  			lock.Lock(key)
    50  			array.Append(1)
    51  			time.Sleep(300 * time.Millisecond)
    52  			lock.Unlock(key)
    53  		}()
    54  		go func() {
    55  			time.Sleep(100 * time.Millisecond)
    56  			lock.Lock(key)
    57  			array.Append(1)
    58  			lock.Unlock(key)
    59  		}()
    60  		time.Sleep(100 * time.Millisecond)
    61  		t.Assert(array.Len(), 1)
    62  		time.Sleep(100 * time.Millisecond)
    63  		t.Assert(array.Len(), 1)
    64  		time.Sleep(200 * time.Millisecond)
    65  		t.Assert(array.Len(), 2)
    66  		lock.Clear()
    67  	})
    68  
    69  }
    70  
    71  func Test_Locker_TryLock(t *testing.T) {
    72  	gtest.C(t, func(t *gtest.T) {
    73  		key := "testTryLock"
    74  		array := garray.New(true)
    75  		go func() {
    76  			gmlock.Lock(key)
    77  			array.Append(1)
    78  			time.Sleep(300 * time.Millisecond)
    79  			gmlock.Unlock(key)
    80  		}()
    81  		go func() {
    82  			time.Sleep(150 * time.Millisecond)
    83  			if gmlock.TryLock(key) {
    84  				array.Append(1)
    85  				gmlock.Unlock(key)
    86  			}
    87  		}()
    88  		go func() {
    89  			time.Sleep(400 * time.Millisecond)
    90  			if gmlock.TryLock(key) {
    91  				array.Append(1)
    92  				gmlock.Unlock(key)
    93  			}
    94  		}()
    95  		time.Sleep(100 * time.Millisecond)
    96  		t.Assert(array.Len(), 1)
    97  		time.Sleep(100 * time.Millisecond)
    98  		t.Assert(array.Len(), 1)
    99  		time.Sleep(300 * time.Millisecond)
   100  		t.Assert(array.Len(), 2)
   101  	})
   102  
   103  }
   104  
   105  func Test_Locker_LockFunc(t *testing.T) {
   106  	//no expire
   107  	gtest.C(t, func(t *gtest.T) {
   108  		key := "testLockFunc"
   109  		array := garray.New(true)
   110  		go func() {
   111  			gmlock.LockFunc(key, func() {
   112  				array.Append(1)
   113  				time.Sleep(300 * time.Millisecond)
   114  			}) //
   115  		}()
   116  		go func() {
   117  			time.Sleep(100 * time.Millisecond)
   118  			gmlock.LockFunc(key, func() {
   119  				array.Append(1)
   120  			})
   121  		}()
   122  		time.Sleep(100 * time.Millisecond)
   123  		t.Assert(array.Len(), 1)
   124  		time.Sleep(100 * time.Millisecond)
   125  		t.Assert(array.Len(), 1) //
   126  		time.Sleep(200 * time.Millisecond)
   127  		t.Assert(array.Len(), 2)
   128  	})
   129  }
   130  
   131  func Test_Locker_TryLockFunc(t *testing.T) {
   132  	//no expire
   133  	gtest.C(t, func(t *gtest.T) {
   134  		key := "testTryLockFunc"
   135  		array := garray.New(true)
   136  		go func() {
   137  			gmlock.TryLockFunc(key, func() {
   138  				array.Append(1)
   139  				time.Sleep(200 * time.Millisecond)
   140  			})
   141  		}()
   142  		go func() {
   143  			time.Sleep(100 * time.Millisecond)
   144  			gmlock.TryLockFunc(key, func() {
   145  				array.Append(1)
   146  			})
   147  		}()
   148  		go func() {
   149  			time.Sleep(300 * time.Millisecond)
   150  			gmlock.TryLockFunc(key, func() {
   151  				array.Append(1)
   152  			})
   153  		}()
   154  		time.Sleep(150 * time.Millisecond)
   155  		t.Assert(array.Len(), 1)
   156  		time.Sleep(400 * time.Millisecond)
   157  		t.Assert(array.Len(), 2)
   158  	})
   159  }
   160  
   161  func Test_Multiple_Goroutine(t *testing.T) {
   162  	gtest.C(t, func(t *gtest.T) {
   163  		ch := make(chan struct{})
   164  		num := 1000
   165  		wait := sync.WaitGroup{}
   166  		wait.Add(num)
   167  		for i := 0; i < num; i++ {
   168  			go func() {
   169  				defer wait.Done()
   170  				<-ch
   171  				gmlock.Lock("test")
   172  				defer gmlock.Unlock("test")
   173  				time.Sleep(time.Millisecond)
   174  			}()
   175  		}
   176  		close(ch)
   177  		wait.Wait()
   178  	})
   179  
   180  	gtest.C(t, func(t *gtest.T) {
   181  		ch := make(chan struct{})
   182  		num := 100
   183  		wait := sync.WaitGroup{}
   184  		wait.Add(num * 2)
   185  		for i := 0; i < num; i++ {
   186  			go func() {
   187  				defer wait.Done()
   188  				<-ch
   189  				gmlock.Lock("test")
   190  				defer gmlock.Unlock("test")
   191  				time.Sleep(time.Millisecond)
   192  			}()
   193  		}
   194  		for i := 0; i < num; i++ {
   195  			go func() {
   196  				defer wait.Done()
   197  				<-ch
   198  				gmlock.RLock("test")
   199  				defer gmlock.RUnlock("test")
   200  				time.Sleep(time.Millisecond)
   201  			}()
   202  		}
   203  		close(ch)
   204  		wait.Wait()
   205  	})
   206  }
   207  
   208  func Test_Locker_RLock(t *testing.T) {
   209  	// RLock before Lock
   210  	gtest.C(t, func(t *gtest.T) {
   211  		key := "testRLockBeforeLock"
   212  		array := garray.New(true)
   213  		go func() {
   214  			gmlock.RLock(key)
   215  			array.Append(1)
   216  			time.Sleep(200 * time.Millisecond)
   217  			gmlock.RUnlock(key)
   218  		}()
   219  		go func() {
   220  			time.Sleep(100 * time.Millisecond)
   221  			gmlock.Lock(key)
   222  			array.Append(1)
   223  			gmlock.Unlock(key)
   224  		}()
   225  		time.Sleep(100 * time.Millisecond)
   226  		t.Assert(array.Len(), 1)
   227  		time.Sleep(200 * time.Millisecond)
   228  		t.Assert(array.Len(), 2)
   229  	})
   230  
   231  	// Lock before RLock
   232  	gtest.C(t, func(t *gtest.T) {
   233  		key := "testLockBeforeRLock"
   234  		array := garray.New(true)
   235  		go func() {
   236  			gmlock.Lock(key)
   237  			array.Append(1)
   238  			time.Sleep(200 * time.Millisecond)
   239  			gmlock.Unlock(key)
   240  		}()
   241  		go func() {
   242  			time.Sleep(100 * time.Millisecond)
   243  			gmlock.RLock(key)
   244  			array.Append(1)
   245  			gmlock.RUnlock(key)
   246  		}()
   247  		time.Sleep(100 * time.Millisecond)
   248  		t.Assert(array.Len(), 1)
   249  		time.Sleep(200 * time.Millisecond)
   250  		t.Assert(array.Len(), 2)
   251  	})
   252  
   253  	// Lock before RLocks
   254  	gtest.C(t, func(t *gtest.T) {
   255  		key := "testLockBeforeRLocks"
   256  		array := garray.New(true)
   257  		go func() {
   258  			gmlock.Lock(key)
   259  			array.Append(1)
   260  			time.Sleep(300 * time.Millisecond)
   261  			gmlock.Unlock(key)
   262  		}()
   263  		go func() {
   264  			time.Sleep(100 * time.Millisecond)
   265  			gmlock.RLock(key)
   266  			array.Append(1)
   267  			time.Sleep(200 * time.Millisecond)
   268  			gmlock.RUnlock(key)
   269  		}()
   270  		go func() {
   271  			time.Sleep(100 * time.Millisecond)
   272  			gmlock.RLock(key)
   273  			array.Append(1)
   274  			time.Sleep(200 * time.Millisecond)
   275  			gmlock.RUnlock(key)
   276  		}()
   277  		time.Sleep(200 * time.Millisecond)
   278  		t.Assert(array.Len(), 1)
   279  		time.Sleep(200 * time.Millisecond)
   280  		t.Assert(array.Len(), 3)
   281  	})
   282  }
   283  
   284  func Test_Locker_TryRLock(t *testing.T) {
   285  	// Lock before TryRLock
   286  	gtest.C(t, func(t *gtest.T) {
   287  		key := "testLockBeforeTryRLock"
   288  		array := garray.New(true)
   289  		go func() {
   290  			gmlock.Lock(key)
   291  			array.Append(1)
   292  			time.Sleep(200 * time.Millisecond)
   293  			gmlock.Unlock(key)
   294  		}()
   295  		go func() {
   296  			time.Sleep(100 * time.Millisecond)
   297  			if gmlock.TryRLock(key) {
   298  				array.Append(1)
   299  				gmlock.RUnlock(key)
   300  			}
   301  		}()
   302  		time.Sleep(150 * time.Millisecond)
   303  		t.Assert(array.Len(), 1)
   304  		time.Sleep(200 * time.Millisecond)
   305  		t.Assert(array.Len(), 1)
   306  	})
   307  
   308  	// Lock before TryRLocks
   309  	gtest.C(t, func(t *gtest.T) {
   310  		key := "testLockBeforeTryRLocks"
   311  		array := garray.New(true)
   312  		go func() {
   313  			gmlock.Lock(key)
   314  			array.Append(1)
   315  			time.Sleep(200 * time.Millisecond)
   316  			gmlock.Unlock(key)
   317  		}()
   318  		go func() {
   319  			time.Sleep(100 * time.Millisecond)
   320  			if gmlock.TryRLock(key) {
   321  				array.Append(1)
   322  				gmlock.RUnlock(key)
   323  			}
   324  		}()
   325  		go func() {
   326  			time.Sleep(300 * time.Millisecond)
   327  			if gmlock.TryRLock(key) {
   328  				array.Append(1)
   329  				gmlock.RUnlock(key)
   330  			}
   331  		}()
   332  		time.Sleep(150 * time.Millisecond)
   333  		t.Assert(array.Len(), 1)
   334  		time.Sleep(200 * time.Millisecond)
   335  		t.Assert(array.Len(), 2)
   336  	})
   337  }
   338  
   339  func Test_Locker_RLockFunc(t *testing.T) {
   340  	// RLockFunc before Lock
   341  	gtest.C(t, func(t *gtest.T) {
   342  		key := "testRLockFuncBeforeLock"
   343  		array := garray.New(true)
   344  		go func() {
   345  			gmlock.RLockFunc(key, func() {
   346  				array.Append(1)
   347  				time.Sleep(200 * time.Millisecond)
   348  			})
   349  		}()
   350  		go func() {
   351  			time.Sleep(100 * time.Millisecond)
   352  			gmlock.Lock(key)
   353  			array.Append(1)
   354  			gmlock.Unlock(key)
   355  		}()
   356  		time.Sleep(150 * time.Millisecond)
   357  		t.Assert(array.Len(), 1)
   358  		time.Sleep(200 * time.Millisecond)
   359  		t.Assert(array.Len(), 2)
   360  	})
   361  
   362  	// Lock before RLockFunc
   363  	gtest.C(t, func(t *gtest.T) {
   364  		key := "testLockBeforeRLockFunc"
   365  		array := garray.New(true)
   366  		go func() {
   367  			gmlock.Lock(key)
   368  			array.Append(1)
   369  			time.Sleep(200 * time.Millisecond)
   370  			gmlock.Unlock(key)
   371  		}()
   372  		go func() {
   373  			time.Sleep(100 * time.Millisecond)
   374  			gmlock.RLockFunc(key, func() {
   375  				array.Append(1)
   376  			})
   377  		}()
   378  		time.Sleep(100 * time.Millisecond)
   379  		t.Assert(array.Len(), 1)
   380  		time.Sleep(200 * time.Millisecond)
   381  		t.Assert(array.Len(), 2)
   382  	})
   383  
   384  	// Lock before RLockFuncs
   385  	gtest.C(t, func(t *gtest.T) {
   386  		key := "testLockBeforeRLockFuncs"
   387  		array := garray.New(true)
   388  		go func() {
   389  			gmlock.Lock(key)
   390  			array.Append(1)
   391  			time.Sleep(200 * time.Millisecond)
   392  			gmlock.Unlock(key)
   393  		}()
   394  		go func() {
   395  			time.Sleep(100 * time.Millisecond)
   396  			gmlock.RLockFunc(key, func() {
   397  				array.Append(1)
   398  				time.Sleep(200 * time.Millisecond)
   399  			})
   400  		}()
   401  		go func() {
   402  			time.Sleep(100 * time.Millisecond)
   403  			gmlock.RLockFunc(key, func() {
   404  				array.Append(1)
   405  				time.Sleep(200 * time.Millisecond)
   406  			})
   407  		}()
   408  		time.Sleep(100 * time.Millisecond)
   409  		t.Assert(array.Len(), 1)
   410  		time.Sleep(200 * time.Millisecond)
   411  		t.Assert(array.Len(), 3)
   412  	})
   413  }
   414  
   415  func Test_Locker_TryRLockFunc(t *testing.T) {
   416  	// Lock before TryRLockFunc
   417  	gtest.C(t, func(t *gtest.T) {
   418  		key := "testLockBeforeTryRLockFunc"
   419  		array := garray.New(true)
   420  		go func() {
   421  			gmlock.Lock(key)
   422  			array.Append(1)
   423  			time.Sleep(200 * time.Millisecond)
   424  			gmlock.Unlock(key)
   425  		}()
   426  		go func() {
   427  			time.Sleep(100 * time.Millisecond)
   428  			gmlock.TryRLockFunc(key, func() {
   429  				array.Append(1)
   430  			})
   431  		}()
   432  		time.Sleep(100 * time.Millisecond)
   433  		t.Assert(array.Len(), 1)
   434  		time.Sleep(200 * time.Millisecond)
   435  		t.Assert(array.Len(), 1)
   436  	})
   437  
   438  	// Lock before TryRLockFuncs
   439  	gtest.C(t, func(t *gtest.T) {
   440  		key := "testLockBeforeTryRLockFuncs"
   441  		array := garray.New(true)
   442  		go func() {
   443  			gmlock.Lock(key)
   444  			array.Append(1)
   445  			time.Sleep(200 * time.Millisecond)
   446  			gmlock.Unlock(key)
   447  		}()
   448  		go func() {
   449  			time.Sleep(100 * time.Millisecond)
   450  			gmlock.TryRLockFunc(key, func() {
   451  				array.Append(1)
   452  			})
   453  		}()
   454  		go func() {
   455  			time.Sleep(300 * time.Millisecond)
   456  			gmlock.TryRLockFunc(key, func() {
   457  				array.Append(1)
   458  			})
   459  		}()
   460  		time.Sleep(100 * time.Millisecond)
   461  		t.Assert(array.Len(), 1)
   462  		time.Sleep(300 * time.Millisecond)
   463  		t.Assert(array.Len(), 2)
   464  	})
   465  }