github.com/bruceshao/lockfree@v1.1.3-0.20230816090528-e89824c0a6e9/example/simple/main.go (about)

     1  /*
     2   * Copyright (C) THL A29 Limited, a Tencent company. All rights reserved.
     3   *
     4   * SPDX-License-Identifier: Apache-2.0
     5   *
     6   */
     7  
     8  package main
     9  
    10  import (
    11  	"fmt"
    12  	"sync"
    13  	"sync/atomic"
    14  	"time"
    15  
    16  	"github.com/bruceshao/lockfree"
    17  )
    18  
    19  var (
    20  	goSize    = 10000
    21  	sizePerGo = 10000
    22  
    23  	total = goSize * sizePerGo
    24  )
    25  
    26  func main() {
    27  	// lockfree计时
    28  	now := time.Now()
    29  
    30  	// 创建事件处理器
    31  	handler := &eventHandler[uint64]{
    32  		signal: make(chan struct{}, 0),
    33  		now:    now,
    34  	}
    35  
    36  	// 创建消费端串行处理的Lockfree
    37  	lf := lockfree.NewLockfree[uint64](
    38  		1024*1024,
    39  		handler,
    40  		lockfree.NewSleepBlockStrategy(time.Millisecond),
    41  	)
    42  
    43  	// 启动Lockfree
    44  	if err := lf.Start(); err != nil {
    45  		panic(err)
    46  	}
    47  
    48  	// 获取生产者对象
    49  	producer := lf.Producer()
    50  
    51  	// 并发写入
    52  	var wg sync.WaitGroup
    53  	wg.Add(goSize)
    54  	for i := 0; i < goSize; i++ {
    55  		go func(start int) {
    56  			for j := 0; j < sizePerGo; j++ {
    57  				err := producer.Write(uint64(start*sizePerGo + j + 1))
    58  				if err != nil {
    59  					panic(err)
    60  				}
    61  			}
    62  			wg.Done()
    63  		}(i)
    64  	}
    65  
    66  	// wait for producer
    67  	wg.Wait()
    68  
    69  	fmt.Printf("producer has been writed, write count: %v, time cost: %v \n", total, time.Since(now).String())
    70  
    71  	// wait for consumer
    72  	handler.wait()
    73  
    74  	// 关闭Lockfree
    75  	lf.Close()
    76  }
    77  
    78  type eventHandler[T uint64] struct {
    79  	signal   chan struct{}
    80  	gcounter uint64
    81  	now      time.Time
    82  }
    83  
    84  func (h *eventHandler[T]) OnEvent(v uint64) {
    85  	cur := atomic.AddUint64(&h.gcounter, 1)
    86  	if cur == uint64(total) {
    87  		fmt.Printf("eventHandler has been consumed already, read count: %v, time cose: %v\n", total, time.Since(h.now))
    88  		close(h.signal)
    89  		return
    90  	}
    91  
    92  	if cur%10000000 == 0 {
    93  		fmt.Printf("eventHandler consume %v\n", cur)
    94  	}
    95  }
    96  
    97  func (h *eventHandler[T]) wait() {
    98  	<-h.signal
    99  }