欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

golang實(shí)現(xiàn)協(xié)程池的方法示例

 更新時(shí)間:2025年02月06日 09:34:05   作者:陳墨1234  
本文主要介紹了golang實(shí)現(xiàn)協(xié)程池的方法示例,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

go協(xié)程池可以看成一個(gè)被初始化的固定大小的協(xié)程循環(huán)讀取函數(shù)隊(duì)列,獲取是否有可供調(diào)用的函數(shù)隊(duì)列,如果有,則協(xié)程池中的一個(gè)協(xié)程調(diào)用并執(zhí)行該函數(shù),talk is cheap,show me the code。

主體協(xié)程池代碼如下所示:

package goroutine

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

// go實(shí)現(xiàn)簡(jiǎn)單協(xié)程池
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(), //自定義自旋鎖實(shí)現(xiàn),如果使用go自帶的鎖,則可能會(huì)出現(xiàn)死鎖問題
	}
	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 (p *Pool) Put(fc fn) {
	p.lock.Lock()
	p.tasks = append(p.tasks, fc)
	p.lock.Unlock()
}

自定義的自旋鎖實(shí)現(xiàn)代碼如下:

package goroutine

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

type spinLock uint32

const maxBackoff = 16

func (sl *spinLock) Lock() {
	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)
}

測(cè)試用的代碼如下所示

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)
}

開發(fā)環(huán)境為goland,運(yùn)行結(jié)果截圖如下圖:

=== 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 23: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/08/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

好了,整體代碼介紹完了,希望你能對(duì)協(xié)程池有個(gè)比較簡(jiǎn)單的了解,也可以基于此代碼,豐富一下邏輯

到此這篇關(guān)于golang實(shí)現(xiàn)協(xié)程池的方法示例的文章就介紹到這了,更多相關(guān)golang 協(xié)程池內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • golang 獲取當(dāng)前執(zhí)行程序路徑的操作

    golang 獲取當(dāng)前執(zhí)行程序路徑的操作

    這篇文章主要介紹了golang 獲取當(dāng)前程序執(zhí)行路徑的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2020-12-12
  • Go語言面試題之select和channel的用法

    Go語言面試題之select和channel的用法

    金九銀十面試季到了(PS:貌似今年一年都是面試季),就業(yè)環(huán)境很差,導(dǎo)致從業(yè)人員不得不卷。本文將重點(diǎn)講解一下Go面試進(jìn)階知識(shí)點(diǎn)之select和channel,需要的可以參考一下
    2022-09-09
  • Golang設(shè)計(jì)模式之生成器模式講解和代碼示例

    Golang設(shè)計(jì)模式之生成器模式講解和代碼示例

    生成器是一種創(chuàng)建型設(shè)計(jì)模式,使你能夠分步驟創(chuàng)建復(fù)雜對(duì)象,與其他創(chuàng)建型模式不同,生成器不要求產(chǎn)品擁有通用接口,這使得用相同的創(chuàng)建過程生成不同的產(chǎn)品成為可能,本文就通過代碼示例為大家詳細(xì)介紹Golang生成器模式,感興趣的同學(xué)可以參考下
    2023-06-06
  • 如何在Go中使用切片容量和長(zhǎng)度

    如何在Go中使用切片容量和長(zhǎng)度

    這篇文章主要介紹了如何在Go中使用切片容量和長(zhǎng)度,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-11-11
  • golang如何使用struct的tag屬性的詳細(xì)介紹

    golang如何使用struct的tag屬性的詳細(xì)介紹

    這篇文章主要介紹了golang如何使用struct的tag屬性的詳細(xì)介紹,從例子說起,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2018-11-11
  • golang NewRequest/gorequest實(shí)現(xiàn)http請(qǐng)求的示例代碼

    golang NewRequest/gorequest實(shí)現(xiàn)http請(qǐng)求的示例代碼

    本文主要介紹了golang NewRequest/gorequest實(shí)現(xiàn)http請(qǐng)求的示例代碼,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-08-08
  • go 原生http web 服務(wù)跨域restful api的寫法介紹

    go 原生http web 服務(wù)跨域restful api的寫法介紹

    這篇文章主要介紹了go 原生http web 服務(wù)跨域restful api的寫法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2021-04-04
  • Go實(shí)現(xiàn)socks5服務(wù)器的方法

    Go實(shí)現(xiàn)socks5服務(wù)器的方法

    SOCKS5 是一個(gè)代理協(xié)議,它在使用TCP/IP協(xié)議通訊的前端機(jī)器和服務(wù)器機(jī)器之間扮演一個(gè)中介角色,使得內(nèi)部網(wǎng)中的前端機(jī)器變得能夠訪問Internet網(wǎng)中的服務(wù)器,或者使通訊更加安全,這篇文章主要介紹了Go實(shí)現(xiàn)socks5服務(wù)器的方法,需要的朋友可以參考下
    2023-07-07
  • Go語言之init函數(shù)

    Go語言之init函數(shù)

    Go語言有一個(gè)特殊的函數(shù)init,先于main函數(shù)執(zhí)行,實(shí)現(xiàn)包級(jí)別的一些初始化操作。這篇文章介紹了Go中的Init函數(shù),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-07-07
  • Go語言中獲取IP地址的方法小結(jié)

    Go語言中獲取IP地址的方法小結(jié)

    這篇文章主要為大家詳細(xì)介紹了Go語言中獲取IP地址的常用方法,文中的示例代碼講解詳細(xì),具有一定的學(xué)習(xí)價(jià)值,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2023-12-12

最新評(píng)論