国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

golang Goroutine超時(shí)控制

這篇具有很好參考價(jià)值的文章主要介紹了golang Goroutine超時(shí)控制。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問(wèn)。

1.個(gè)人理解?

package main

import (
	"context"
	"fmt"
	"runtime"
	"time"
)

func main() {
	// 為了方便查看設(shè)置的計(jì)數(shù)器
	//go func() {
	//	var o int64
	//	for {
	//		o++
	//		fmt.Println(o)
	//		time.Sleep(time.Second)
	//	}
	//}()

	// 開(kāi)啟協(xié)程
	for i := 0; i < 100; i++ {

		go func(i int) {
			// 利用context 設(shè)置超時(shí)上下文
			ctx, cancel := context.WithTimeout(context.TODO(), 2*time.Second)
			// 主動(dòng)退出信號(hào)
			endDone := make(chan struct{})

			// 再次開(kāi)啟子協(xié)程異步處理業(yè)務(wù)邏輯
			go func() {
				select {
				// 監(jiān)聽(tīng)是否超時(shí)
				case <-ctx.Done():
					fmt.Println("Goroutine timeout")
					return
				// 處理業(yè)務(wù)邏輯
				default:
					if i == 1 {
						time.Sleep(10 * time.Second)
					}

					// 此處代碼會(huì)繼續(xù)執(zhí)行
					//fmt.Println("代碼邏輯繼續(xù)執(zhí)行")

					// 主動(dòng)退出
					close(endDone)
                    
                    return
				}
			}()

			// 監(jiān)聽(tīng)父協(xié)程狀態(tài)
			select {
			// 超時(shí)退出父協(xié)程,這里需要注意此時(shí)如果子協(xié)程已經(jīng)執(zhí)行并超時(shí),子協(xié)程會(huì)繼續(xù)執(zhí)行中直到關(guān)閉,這塊需要關(guān)注下。比如:查看數(shù)據(jù)確定數(shù)據(jù)是否已被修改等。
			case <-ctx.Done():
				fmt.Println("超時(shí)退出", i)
				cancel()
				return
			// 主動(dòng)關(guān)閉
			case <-endDone:
				fmt.Println("主動(dòng)退出", i)
				cancel()
				return
			}
		}(i)

	}

	//time.Sleep(8 * time.Second)
	time.Sleep(12 * time.Second)

	// 查看當(dāng)前還存在多少運(yùn)行中的goroutine
	fmt.Println("number of goroutines:", runtime.NumGoroutine())
}

2.go-zero實(shí)現(xiàn)方式

package main

import (
	"context"
	"fmt"
	"runtime/debug"
	"strings"
	"time"
)

var (
	// ErrCanceled是取消上下文時(shí)返回的錯(cuò)誤。
	ErrCanceled = context.Canceled
	// ErrTimeout是當(dāng)上下文的截止日期過(guò)去時(shí)返回的錯(cuò)誤。
	ErrTimeout = context.DeadlineExceeded
)

// DoOption定義了自定義DoWithTimeout調(diào)用的方法。
type DoOption func() context.Context

// DoWithTimeout運(yùn)行帶有超時(shí)控制的fn。
func DoWithTimeout(fn func() error, timeout time.Duration, opts ...DoOption) error {
	parentCtx := context.Background()
	for _, opt := range opts {
		parentCtx = opt()
	}
	ctx, cancel := context.WithTimeout(parentCtx, timeout)
	defer cancel()

	// 創(chuàng)建緩沖區(qū)大小為1的通道以避免goroutine泄漏
	done := make(chan error, 1)
	panicChan := make(chan interface{}, 1)
	go func() {
		defer func() {
			if p := recover(); p != nil {
				// 附加調(diào)用堆棧以避免在不同的goroutine中丟失
				panicChan <- fmt.Sprintf("%+v\n\n%s", p, strings.TrimSpace(string(debug.Stack())))
			}
		}()
		done <- fn()
	}()

	select {
	case p := <-panicChan:
		panic(p)
	case err := <-done:
		return err
	case <-ctx.Done():
		return ctx.Err()
	}
}

// WithContext使用給定的ctx自定義DoWithTimeout調(diào)用。
func WithContext(ctx context.Context) DoOption {
	return func() context.Context {
		return ctx
	}
}

func main() {
	ctx, cancel := context.WithCancel(context.Background())
	go func() {
		fmt.Println(1111)
		time.Sleep(time.Second * 5)
		fmt.Println(2222)
		cancel()
	}()

	err := DoWithTimeout(func() error {
		fmt.Println("aaaa")
		time.Sleep(10 * time.Second)
		fmt.Println("bbbb")
		return nil
	}, 3*time.Second, WithContext(ctx))

	fmt.Println(err)

	time.Sleep(15 * time.Second)

	//err := DoWithTimeout(func() error {
	//	fmt.Println(111)
	//	time.Sleep(time.Second * 3)
	//	fmt.Println(222)
	//	return nil
	//}, time.Second*2)
	//
	//fmt.Println(err)
	//time.Sleep(6 * time.Second)
	//
	//fmt.Println("number of goroutines:", runtime.NumGoroutine())
}
package fx

import (
	"context"
	"testing"
	"time"

	"github.com/stretchr/testify/assert"
)

func TestWithPanic(t *testing.T) {
	assert.Panics(t, func() {
		_ = DoWithTimeout(func() error {
			panic("hello")
		}, time.Millisecond*50)
	})
}

func TestWithTimeout(t *testing.T) {
	assert.Equal(t, ErrTimeout, DoWithTimeout(func() error {
		time.Sleep(time.Millisecond * 50)
		return nil
	}, time.Millisecond))
}

func TestWithoutTimeout(t *testing.T) {
	assert.Nil(t, DoWithTimeout(func() error {
		return nil
	}, time.Millisecond*50))
}

func TestWithCancel(t *testing.T) {
	ctx, cancel := context.WithCancel(context.Background())
	go func() {
		time.Sleep(time.Millisecond * 10)
		cancel()
	}()
	err := DoWithTimeout(func() error {
		time.Sleep(time.Minute)
		return nil
	}, time.Second, WithContext(ctx))
	assert.Equal(t, ErrCanceled, err)
}

參考文獻(xiàn):

?https://github.com/zeromicro/go-zero/blob/master/core/fx/timeout.go

?一文搞懂 Go 超時(shí)控制_51CTO博客_go 超時(shí)處理文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-704757.html

到了這里,關(guān)于golang Goroutine超時(shí)控制的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來(lái)自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • GO語(yǔ)言網(wǎng)絡(luò)編程(并發(fā)編程)并發(fā)介紹,Goroutine

    GO語(yǔ)言網(wǎng)絡(luò)編程(并發(fā)編程)并發(fā)介紹,Goroutine

    進(jìn)程和線程 并發(fā)和并行 協(xié)程和線程 協(xié)程:獨(dú)立的??臻g,共享堆空間,調(diào)度由用戶自己控制,本質(zhì)上有點(diǎn)類似于用戶級(jí)線程,這些用戶級(jí)線程的調(diào)度也是自己實(shí)現(xiàn)的。 線程:一個(gè)線程上可以跑多個(gè)協(xié)程,協(xié)程是輕量級(jí)的線程。 goroutine 只是由官方實(shí)現(xiàn)的超級(jí)\\\"線程池\\\"。 每個(gè)

    2024年02月09日
    瀏覽(92)
  • 【Golang】go編程語(yǔ)言適合哪些項(xiàng)目開(kāi)發(fā)?

    【Golang】go編程語(yǔ)言適合哪些項(xiàng)目開(kāi)發(fā)?

    前言 在當(dāng)今數(shù)字化時(shí)代,軟件開(kāi)發(fā)已成為各行各業(yè)的核心需求之一。 而選擇適合的編程語(yǔ)言對(duì)于項(xiàng)目的成功開(kāi)發(fā)至關(guān)重要。 本文將重點(diǎn)探討Go編程語(yǔ)言適合哪些項(xiàng)目開(kāi)發(fā),以幫助讀者在選擇合適的編程語(yǔ)言時(shí)做出明智的決策。 Go 編程語(yǔ)言適合哪些項(xiàng)目開(kāi)發(fā)? Go是由Google開(kāi)發(fā)

    2024年02月04日
    瀏覽(29)
  • 【golang】Context超時(shí)控制與原理

    【golang】Context超時(shí)控制與原理

    在Go語(yǔ)言圈子中流行著一句話: Never start a goroutine without knowing how it will stop。 翻譯:如果你不知道協(xié)程如何退出,就不要使用它。 在創(chuàng)建協(xié)程時(shí),我們可能還會(huì)再創(chuàng)建一些別的子協(xié)程,那么這些協(xié)程的退出就成了問(wèn)題。在Go1.7之后,Go官方引入了Context來(lái)實(shí)現(xiàn)協(xié)程的退出。不僅

    2024年01月22日
    瀏覽(19)
  • 【Golang】VsCode下開(kāi)發(fā)Go語(yǔ)言的環(huán)境配置(超詳細(xì)圖文詳解)

    【Golang】VsCode下開(kāi)發(fā)Go語(yǔ)言的環(huán)境配置(超詳細(xì)圖文詳解)

    ??推薦網(wǎng)站(不斷完善中):個(gè)人博客 ??個(gè)人主頁(yè):個(gè)人主頁(yè) ??相關(guān)專欄:CSDN專欄、個(gè)人專欄 ??立志賺錢(qián),干活想躺,瞎分享的摸魚(yú)工程師一枚 ? 話說(shuō)在前,Go語(yǔ)言的編碼方式是 UTF-8 ,理論上你直接使用文本進(jìn)行編輯也是可以的,當(dāng)然為了提升我們的開(kāi)發(fā)效率我們還是需

    2024年02月07日
    瀏覽(27)
  • Go 里的超時(shí)控制

    Go 里的超時(shí)控制

    日常開(kāi)發(fā)中我們大概率會(huì)遇到超時(shí)控制的場(chǎng)景,比如一個(gè)批量耗時(shí)任務(wù)、網(wǎng)絡(luò)請(qǐng)求等;一個(gè)良好的超時(shí)控制可以有效的避免一些問(wèn)題(比如 goroutine 泄露、資源不釋放等)。 在 go 中實(shí)現(xiàn)超時(shí)控制的方法非常簡(jiǎn)單,首先第一種方案是 Time.After(d Duration): output: time.After() 會(huì)返回一

    2024年02月07日
    瀏覽(11)
  • golang協(xié)程goroutine教程

    項(xiàng)目經(jīng)常遇到一些批量任務(wù)執(zhí)行太慢,需要開(kāi)啟多線程去處理,記錄下在 Golang 中協(xié)程使用的一些操作。 協(xié)程是計(jì)算機(jī)程序的一類組件,推廣了協(xié)作式多任務(wù)的子例程,允許執(zhí)行被掛起與被恢復(fù)。相對(duì)子例程而言,協(xié)程更為一般和靈活,但在實(shí)踐中使用沒(méi)有子例程那樣廣泛。

    2024年02月02日
    瀏覽(35)
  • golang學(xué)習(xí)-goroutine

    1、goroutine協(xié)程 goroutine 是 Go 語(yǔ)言支持并發(fā)的核心,一個(gè)goroutine會(huì)以一個(gè)很小的棧開(kāi)始其生命周期,一般只需要2KB。區(qū)別于操作系統(tǒng)線程由系統(tǒng)內(nèi)核進(jìn)行調(diào)度, goroutine 是由Go運(yùn)行時(shí)(runtime)負(fù)責(zé)調(diào)度。例如Go運(yùn)行時(shí)會(huì)智能地將 m個(gè)goroutine 合理地分配給n個(gè)操作系統(tǒng)線程,實(shí)現(xiàn)類

    2024年01月18日
    瀏覽(32)
  • 深入理解 Golang: Goroutine 協(xié)程

    深入理解 Golang: Goroutine 協(xié)程

    進(jìn)程用來(lái)分配內(nèi)存空間,是操作系統(tǒng)分配資源的最小單位;線程用來(lái)分配 CPU 時(shí)間,多個(gè)線程共享內(nèi)存空間,是操作系統(tǒng)或 CPU 調(diào)度的最小單位;協(xié)程用來(lái)精細(xì)利用線程。協(xié)程就是將一段程序的運(yùn)行狀態(tài)打包,可以在線程之間調(diào)度?;蛘哒f(shuō)將一段生產(chǎn)流程打包,使流程不固定在

    2024年02月11日
    瀏覽(20)
  • Golang中的協(xié)程(goroutine)

    Golang中的協(xié)程(goroutine)

    目錄 進(jìn)程 線程 并發(fā) 并行 協(xié)程(goroutine) ?使用sync.WaitGroup等待協(xié)程執(zhí)行完畢 多協(xié)程和多線程 ????????進(jìn)程就是程序在操作系統(tǒng)中的一次執(zhí)行過(guò)程,是系統(tǒng)進(jìn)行資源分配和調(diào)度的基本單位,進(jìn)程是一個(gè)動(dòng)態(tài)概念,是程序在執(zhí)行過(guò)程中分配和管理資源的基本單位,每一個(gè)進(jìn)程

    2024年02月05日
    瀏覽(18)
  • Golang goroutine MPG 模式淺析

    Golang goroutine MPG 模式淺析

    快速入門(mén)小結(jié): (1) 主線程是一個(gè)物理線程,直接作用在cpu上的 。是重量級(jí)的,非常耗費(fèi)cpu資源。 (2)協(xié)程從主線程開(kāi)局的,是輕量級(jí)的線程,是邏輯態(tài),對(duì)資源消耗相對(duì)小。 (3)Golang的協(xié)程機(jī)制是重要的特點(diǎn),可以輕松的開(kāi)啟上萬(wàn)個(gè)協(xié)程。其它編程語(yǔ)言的并發(fā)機(jī)制是

    2024年02月08日
    瀏覽(23)

覺(jué)得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包