开发者

golang实现协程池的方法示例

go协程池可以看成一个被初始化的固定大小的协程循环读取函数队列,获取是否有可供调用的函数队列,如果有,则协程池中的一个协程调用并执行该函数,talk is cheap,show me the code。

主体协程池代码如下所示:

package goroutine

import (
	"context"
	"fmt"
	"sync"
)

// go实现简单协程池
type Pool struct {
	ctx   context.Context
	tasks []fn
	lock  sync.Locker
}

type fn func()

func Init(ctx context.Context, cnt int) *Pool {
	pool := &Pool{
		ctx:   ctx,
		tasks: make([]fn, 0),
		lock:  NewSpinLock(), //自定义自旋锁实现,如果使用go自带的锁,则可能会出现死锁问题
	}
	for i := 0; i < cnt; i++ {
		go func(pool *Pool, idx int) {
			for {
				select {
				case <-pool.ctx.Done():
					fmt.Println("pool exit", idx)
					return
				default:
					fmt.Println("pool exec:", idx)
					pool.lock.Lock()
					if len(pool.tasks) == 0 {
						pool.lock.Unlock()
						continue
					}
					fc := pool.tasks[0]
					pool.tasks = pool.tasks[1:]
					pool.lock.Unlock()
					fc()
				}
			}

		}(pool, i)
	}
	return pool
}

func (www.devze.comp *Pool) Put(fc fn) {
	p.lock.Lock()
	p.tasks = append(p.tasks, fc)
	p.lock.Unlock()
}

自定义的自旋锁实现代码如下:

package goroutine

import (
	"runtime"
	"sync"
	"sync/atomic"
)

type spinLock uint32

const maxBackoff = 16

func (sl *spinLock) Lockpython() {
	backoff := 1
	for !atomic.CompareAndSwapUint32((*uint32)(sl), 0, 1) {
		// Leverage the exponential backoff algorithm, see https://en.wikipedia.org/wiki/Exponential_backoff.
		for i := 0; i < backoff; i++ {
			runtime.Gosched()
		}
		if backoff < maxBackoff {
			backoff <<= 1
		}
	}
}

func (sl *spinLock) Unlock() {
	atomic.StoreUint32((*uint32)(sl), 0)
}

// NewSpinLock instantiates a spin-lock.
func NewSpinLock() sync.Locker {
	return new(spinLock)
}

测试用的代码如下所示

package goroutine

import (
	"context"
	"fmt"
	"log"
	"strconv"
	"sync"
	"testing"
	"time"
)

func TestPool(t *testing.T) {
	ctx := context.Background()
	ctx1, cancel := context.WithCancel(ctx)
	pool := Init(ctx1, 10)
	wg := sync.WaitGroup{}
	for i := 100; i >= 0; i-- {
		wg.Add(1)
		go pool.Put(func() {
			wg.Done()
			log.Println("hello,world" + strconv.Itoa(i))
		})
	}
	wg.Wait()
	cancel()
	time.Sleep(time.Second)
}

开发环境为goland,运行结果截图如下图:

=== RUN   TestPool

pool exec: 0

pool exec: 0

pool exec: 0

pool exec: 0

pool exec: 0

pool exec: 0

pool exec: 0

pool exec: 0

pool exec: 0

pool exec: 0

pool exec: 0

pool exec: 0

pool exec: 0

pool exec: 0

pool exec: 0

pool exec: 0

pool exec: 0

pool exec: 0

pool exec: 0

pool exec: 0

pool exec: 0

pool exec: 0

pool exec: 0

pool exec: 0

pool exec: 0

pool exec: 0

pool exec: 0

pool exec: 0

pool exec: 0

pool exec: 0

pool exec: 0

pool exec: 0

pool exec: 0

pool exec: 0

pool exec: 0

pool exec: 0

pool exec: 0

pool exec: 0

pool exec: 0

pool exec: 0

pool exec: 0

pool exec: 0

pool exec: 0

pool exec: 0

pool exec: 0

pool exec: 0

pool exec: 0

pool exec: 0

pool exec: 0

pool exec: 2

pool exec: 0

pool exec: 1

pool exec: 3

pool exec: 4

pool exec: 7

pool exec: 8

pool exec: 5

pool exec: 6

pool exec: 9

2024/08/02 23:06:20 hello,world97

pool exec: 2

2024/08/02 23:06:20 hello,world42

pool exec: 2

2024/08/02 23:06:20 hello,world57

pool exec: 2

2024/08/02 23:06:20 hello,world56

pool exec: 2

2024/08/02 23:06:20 hello,world55

pool exec: 2

2024/08/02 23:06:20 hello,world54

pool exec: 2

2024/08/02 23:06:20 hello,world53

pool exec: 2

2024/08/02 23:06:20 hello,world52

pool exec: 2

2024/08/02 23:06:20 hello,world51

pool exec: 2

2024/08/02 23:06:20 hello,world50

pool exec: 2

2024/08/02 23:06:20 hello,world49

pool exec: 2

2024/08/02 23:06:20 hello,world48

pool exec: 2

2024/08/02 23:06:20 hello,world47

pool exec: 2

2024/08/02 23:06:20 hello,world46

pool exec: 2

2024/08/02 23:06:20 hello,world45

pool exec: 2

2024/08/02 23:06:20 hello,world44

pool exec: 2

2024/08/02 23:06:20 hello,world95

pool exec: 0

2024/08/02 23:06:20 hello,world43

pool exec: 2

2024/08/02 23:06:20 hello,world41

pool exec: 2

2024/08/02 23:06:20 hello,world40

pool exec: 2

2024/08/02 23:06:20 hello,world33

pool exec: 0

2024/08/02 23:06:20 hello,world39

pool exec: 2

2024/08/02 23:06:20 hello,world38

pool exec: 0

2024/08/02 23:06:20 hello,world37

2024/08/02 23:06:20 hello,world36

pool exec: 2

pool exec: 0

2024/08/02 23:06:20 hello,world96

pool exec: 4

2024/08/02 23:06:20 hello,world98

2024/08/02 23:06:20 hello,world99

pool exec: 3

2024/08/02 23:06:20 hello,world94

2024/08/02 23:06:20 hello,world32

pool exec: 7

2024/08/02 23:06:20 hello,world35

2024/08/02 23:06:20 hello,world31

pool exec: 7

2024/08/02 23:06:20 hello,world90

pool exec: 9

pool exec: 3

2024/08/02 23:06:20 hello,world28

pool exec: 2

2024/08/02 23:06:20 hello,world29

pool exec: 1

2024/08/02 23:06:20 hello,world24

2024/08/02 23:06:20 hello,world26

pool exec: 2

2024/08/02 23:06:20 hello,world34

pool exec: 1

2024/08/02 23javascript:06:20 hello,world93

pool exec: 9

2024/08/02 23:06:20 hello,world21

pool exec: 8

2024/08/02 23:06:20 hello,world92

pool exec: 1

2024/08/02 23:06:20 hello,world23

pool exec: 5

2024/08/02 23:06:20 hello,world22

pool exec: 3

2024/08/02 23:06:20 hello,world20

pool exec: 8

2024/08/02 23:06:20 hello,world25

pool exec: 1

2024/08/02 23:06:20 hello,world91

2024/08/02 23:06:20 hello,world89

pool exec: 6

2024/08/02 23:06:20 hello,world88

pool exec: 6

2024/0http://www.devze.com8/02 23:06:20 hello,world66

pool exec: 6

2024/08/02 23:06:20 hello,world87

pool exec: 9

2024/08/02 23:06:20 hello,world27

pool exec: 4

2024/08/02 23:06:20 hello,world73

pool exec: 4

2024/08/02 23:06:20 hello,world18

pool exec: 1

2024/08/02 23:06:20 hello,world72

pool exec: 6

pool exec: 9

2024/08/02 23:06:20 hello,world30

pool exec: 5

pool exec: 0

2024/08/02 23:06:20 hello,world81

pool exec: 7

2024/08/02 23:06:20 hello,world68

pool exec: 2

2024/08/02 23:06:20 hello,world74

2024/08/02 23:06:20 hello,world67

pool exec: 3

pool exec: 0

2024/08/02 23:06:20 hello,world79

2024/08/02 23:06:20 hello,world85

2024/08/02 23:06:20 hello,world19

pool exec: 3

2024/08/02 23:06:20 hello,world86

pool exec: 4

2024/08/02 23:06:20 hello,world71

2024/08/02 23:06:20 hello,world77

pool exec: 编程客栈3

2024/08/02 23:06:20 hello,world84

pool exec: 0

2024/08/02 23:06:20 hello,world83

pool exec: 8

pool exec: 9

2024/08/02 23:06:20 hello,world78

pool exec: 4

2024/08/02 23:06:20 hello,world69

pool exec: 2

pool exec: 6

2024/08/02 23:06:20 hello,world76

pool exec: 9

pool exec: 4

2024/08/02 23:06:20 hello,world63

pool exec: 9

2024/08/02 23:06:20 hello,world65

pool exec: 8

2024/08/02 23:06:20 hello,world60

pool exec: 4

2024/08/02 23:06:20 hello,world80

pool exec: 7

2024/08/02 23:06:20 hello,world59

pool exec: 4

2024/08/02 23:06:20 hello,world13

pool exec: 9

2024/08/02 23:06:20 hello,world75

2024/08/02 23:06:20 hello,world16

pool exec: 0

2024/08/02 23:06:20 hello,world15

pool exec: 0

2024/08/02 23:06:20 hello,world14

pool exec: 0

2024/08/02 23:06:20 hello,world11

pool exec: 0

2024/08/02 23:06:20 hello,world58

pool exec: 1

2024/08/02 23:06:20 hello,world82

pool exec: 9

pool exec: 5

2024/08/02 23:06:20 hello,world10

pool exec: 9

2024/08/02 23:06:20 hello,world0

pool exec: 7

pool exec: 0

2024/08/02 23:06:20 hello,world8

pool exec: 7

2024/08/02 23:06:20 hello,world7

2024/08/02 23:06:20 hello,world62

pool exec: 9

pool exec: 2

2024/08/02 23:06:20 hello,world9

pool exec: 2

2024/08/02 23:06:20 hello,world2

pool exec: 2

2024/08/02 23:06:20 hello,world4

pool exec: 9

2024/08/02 23:06:20 hello,world3

pool exec: 9

2024/08/02 23:06:20 hello,world100

pool exec: 9

pool exec: 9

pool exec: 9

2024/08/02 23:06:20 hello,world5

pool exec: 9

pool exec: 9

2024/08/02 23:06:20 hello,world1

pool exec: 9

2024/08/02 23:06:20 hello,world64

pool exec: 0

2024/08/02 23:06:20 hello,world61

pool exit 8

2024/08/02 23:06:20 hello,world70

pool exec: 2

pool exit 2

2024/08/02 23:06:20 hello,world17

pool exit 0

2024/08/02 23:06:20 hello,world12

pool exit 4

2024/08/02 23:06:20 hello,world6

pool exit 7

pool exit 3

pool exec: 9

pool exit 9

pool exit 1

pool exec: 5

pool exit 5

pool exit 6

--- PASS: TestPool (1.00s)

PASS

Process finished with the exit code 0

好了,整体代码介绍完了,希望你能对协程池有个比较简单的了解,也可以基于此代码,丰富一下逻辑

到此这篇关于golang实现协程池的方法示例的文章就介绍到这了,更多相关golang 协程池内容请搜索编程客栈(www.devze.com)以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程客栈(www.devze.com)!

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新开发

开发排行榜