最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

golang中創(chuàng)建協(xié)程以及協(xié)程間的相互通信

 更新時(shí)間:2026年07月08日 09:16:33   作者:忍界英雄  
本文詳細(xì)介紹了在Golang中如何創(chuàng)建協(xié)程,利用協(xié)程的輕量級(jí)特性實(shí)現(xiàn)并發(fā),以及如何通過(guò)管道進(jìn)行協(xié)程間的通信和同步控制,包括無(wú)緩沖和有緩沖管道的區(qū)別,以及sync.WaitGroup在進(jìn)程同步中的應(yīng)用

在golang中創(chuàng)建協(xié)程

在 Go 語(yǔ)言中,使用協(xié)程來(lái)實(shí)現(xiàn)并發(fā)模型。

協(xié)程是 Go 語(yǔ)言的并發(fā)執(zhí)行單元,它比傳統(tǒng)的線程更輕量級(jí),允許我們并發(fā)執(zhí)行多個(gè)任務(wù)。

Go 會(huì)在內(nèi)部使用一組線程來(lái)運(yùn)行創(chuàng)建的協(xié)程,并在這些線程之間高效地分配協(xié)程執(zhí)行,這樣可以在不增加太多操作系統(tǒng)線程的情況下執(zhí)行大量的協(xié)程。

在golang中,我們可以方便的使用go func() {}() 語(yǔ)句用于啟動(dòng)一個(gè)新的協(xié)程(goroutine)。

協(xié)程是 Go 語(yǔ)言的并發(fā)執(zhí)行單元,它比傳統(tǒng)的線程更輕量級(jí),允許我們并發(fā)執(zhí)行多個(gè)任務(wù)。

當(dāng)在函數(shù)調(diào)用前加上 go 關(guān)鍵字時(shí),這個(gè)函數(shù)就會(huì)在新的協(xié)程中異步執(zhí)行。

下面是一個(gè)簡(jiǎn)單的在golang主函數(shù)中創(chuàng)建協(xié)程的例子:

func printNumbers() {
    for i := 1; i <= 5; i++ {
        fmt.Println(i)
        time.Sleep(time.Second)
    }
}

func main() {
    // 啟動(dòng)一個(gè)新的協(xié)程來(lái)執(zhí)行 printNumbers 函數(shù)
    go printNumbers()

    // 主協(xié)程中執(zhí)行其他工作
    for i := 'a'; i <= 'e'; i++ {
        fmt.Printf("%c", i)
        time.Sleep(time.Second)
    }

    // 等待足夠的時(shí)間以確保 printNumbers 協(xié)程可以完成執(zhí)行
    time.Sleep(6 * time.Second)
    fmt.Println("main function finished")
}

我們?cè)谛碌膮f(xié)程中,啟動(dòng)了一個(gè)printNumbers()函數(shù),運(yùn)行結(jié)果如下:a12bc3d4e5

這說(shuō)明我們成功創(chuàng)建了一個(gè)協(xié)程,這個(gè)協(xié)程和主程序并發(fā)運(yùn)行。上述代碼也可以寫(xiě)成下面的形式:

func main() {
    // 啟動(dòng)一個(gè)新的協(xié)程來(lái)執(zhí)行 printNumbers 函數(shù)
    go func(){    for i := 1; i <= 5; i++ {
        fmt.Println(i)
        time.Sleep(time.Second)
    }}()

    // 主協(xié)程中執(zhí)行其他工作
    for i := 'a'; i <= 'e'; i++ {
        fmt.Printf("%c", i)
        time.Sleep(time.Second)
    }

    // 等待足夠的時(shí)間以確保 printNumbers 協(xié)程可以完成執(zhí)行
    time.Sleep(6 * time.Second)
    fmt.Println("main function finished")
}

我們?cè)俅芜\(yùn)行發(fā)現(xiàn),運(yùn)行結(jié)果如下:a1b23c45e,可以看到雖然代碼是一樣的,但是打印出字母和數(shù)字的順序卻不同。

這是為什么呢?因?yàn)槲覀冎婚_(kāi)啟了一個(gè)協(xié)程,并沒(méi)有控制協(xié)程和主程序的執(zhí)行順序,所以每次運(yùn)行,有時(shí)協(xié)程運(yùn)行的快些,有時(shí)主程序運(yùn)行的快些。

那么如果我們想要打印一個(gè)字母,再打印一個(gè)數(shù)字,要怎么辦呢?這就需要用到golang提供的,協(xié)程間的通信機(jī)制。

golang中進(jìn)程間的通信

在gonglang中,可以使用管道來(lái)進(jìn)行協(xié)程間的通信。

管道的創(chuàng)建和使用

通過(guò) make(chan Type)可以創(chuàng)建一個(gè)管道,其中 Type是管道將傳遞的數(shù)據(jù)類型。我們通過(guò)通道對(duì)上述代碼進(jìn)行改造:

func main() {
	ch := make(chan bool)   // 用于從 printNumbers 協(xié)程到主協(xié)程的同步
	done := make(chan bool) // 用于從主協(xié)程到 printNumbers 協(xié)程的同步

	// 啟動(dòng)一個(gè)新的協(xié)程來(lái)執(zhí)行 printNumbers 函數(shù)
	go func() {
		for i := 1; i <= 5; i++ {
			fmt.Printf("%d", i)
			ch <- true // 發(fā)送數(shù)字到主協(xié)程
			<-done     // 等待主協(xié)程的信號(hào)
		}
		close(ch) // 關(guān)閉通道
	}()

	// 主協(xié)程中執(zhí)行其他工作
	for i := 'a'; i <= 'e'; i++ {
		<-ch // 等待來(lái)自 printNumbers 協(xié)程的數(shù)字
		fmt.Printf("%c", i)
		done <- true // 發(fā)送信號(hào)到 printNumbers 協(xié)程
	}

	fmt.Println("main function finished")
}

在上述代碼中,我們通過(guò)通道chdone進(jìn)行進(jìn)程間的消息傳遞,主程序通過(guò)<-ch收到ch通道傳來(lái)的信號(hào)后,才打印出數(shù)字。

同樣,協(xié)程收到來(lái)自主程序通道傳來(lái)的信號(hào)后,再繼續(xù)打印字母。

這樣就可以保證打印的順序始終為1a2b3c4d5。

管道通信中傳遞的值

在我們的代碼中使用了<-ch,即沒(méi)有關(guān)心通道傳來(lái)的具體值,如果需要用到通道傳遞過(guò)來(lái)的值,可以使用a<-ch,這樣通道傳來(lái)的值就會(huì)被存儲(chǔ)在變量a中。

有緩沖的管道通信

此外管道可以是無(wú)緩沖的,也可以是有緩沖的,我們上述使用的是無(wú)緩沖的通道。

無(wú)緩沖管道在發(fā)送和接收之間是同步的:發(fā)送操作會(huì)阻塞,直到另一端的協(xié)程執(zhí)行接收操作,而接收操作也會(huì)阻塞,直到有數(shù)據(jù)被發(fā)送。這種同步通信機(jī)制確保了協(xié)程間的同步執(zhí)行。

有緩沖的管道則允許在協(xié)程間異步傳輸數(shù)據(jù)。當(dāng)你創(chuàng)建一個(gè)有緩沖的管道時(shí),你需要指定緩沖區(qū)的大小。有緩沖的管道可以存儲(chǔ)多個(gè)元素,直到達(dá)到其緩沖區(qū)的容量為止。發(fā)送操作只有在緩沖區(qū)滿時(shí)才會(huì)阻塞,接收操作只有在緩沖區(qū)空時(shí)才會(huì)阻塞。

創(chuàng)建有緩沖的管道的示例:ch := make(chan int, 5)

在這個(gè)例子中,ch 是一個(gè)可以存儲(chǔ)最多 5 個(gè)整數(shù)的有緩沖管道。這意味著我們可以在沒(méi)有接收方的情況下向管道發(fā)送最多 5 個(gè)整數(shù),而不會(huì)發(fā)生阻塞。

golang中進(jìn)程間的同步控制

golang中當(dāng)協(xié)程的父程序即創(chuàng)建協(xié)程的程序結(jié)束時(shí),父程序中的協(xié)程會(huì)全部終止

在文章最開(kāi)始的代碼中,我們通過(guò)使用 time.Sleep(6 * time.Second)來(lái)確保在協(xié)程結(jié)束之前,主程序不會(huì)停止,這其實(shí)是非常不好的做法。

同步原語(yǔ)sync.WaitGroup

實(shí)際上,在gonglang中,一般使用WaitGroup來(lái)進(jìn)行進(jìn)程間的同步控制,確保在子協(xié)程全部結(jié)束時(shí),父協(xié)程才會(huì)終止。

sync.WaitGroup 是 Go 語(yǔ)言中的一個(gè)同步原語(yǔ),用于等待一組協(xié)程(goroutines)的完成。它主要用于確保所有協(xié)程都已經(jīng)完成它們的工作。

WaitGroup中常用的三個(gè)函數(shù):Add()、Done()和Wait()

在使用sync.WaitGroup之前我們首先要學(xué)習(xí)其Add()、Done()和Wait()函數(shù)。

wg.Add(delta int) 方法用于設(shè)置等待組中的協(xié)程數(shù)量。每次調(diào)用 wg.Add() 時(shí),傳遞的參數(shù)(通常是 1)將會(huì)被加到內(nèi)部計(jì)數(shù)器上。這個(gè)方法通常在啟動(dòng)協(xié)程之前調(diào)用,以表明有新的協(xié)程需要等待。

wg.Done() 方法用于表示一個(gè)協(xié)程完成了它的工作。每當(dāng)協(xié)程完成它的執(zhí)行時(shí),它應(yīng)該調(diào)用 wg.Done(),這將從內(nèi)部計(jì)數(shù)器減去 1。

當(dāng)內(nèi)部計(jì)數(shù)器減到 0 時(shí),任何阻塞在 wg.Wait() 調(diào)用上的協(xié)程都會(huì)停止阻塞,繼續(xù)執(zhí)行。

wg使用實(shí)例

通過(guò)下面這個(gè)函數(shù)我們可以確保所有子協(xié)程全部完成之后,主程序才會(huì)終止:

func main() {
	// 啟動(dòng)一個(gè)新的協(xié)程來(lái)執(zhí)行 printNumbers 函數(shù)
	var wg sync.WaitGroup
	// 等待協(xié)程數(shù)增加一
	wg.Add(1)
	go func() {
		for i := 1; i <= 5; i++ {
			fmt.Println(i)
		}
		//協(xié)程完成等待協(xié)程數(shù)減少1
		wg.Done()
	}()

	wg.Add(1)
	go func() {
		for i := 'a'; i <= 'e'; i++ {
			fmt.Printf("%c", i)
		}
		wg.Done()
	}()

	// 等待所有的協(xié)程完成
	wg.Wait()
	fmt.Println("main function finished")
}

通過(guò)這種方法,我們發(fā)現(xiàn),只有當(dāng)兩個(gè)子程序都運(yùn)行完成后,才會(huì)打印出main function finished。

到此這篇關(guān)于golang中創(chuàng)建協(xié)程以及協(xié)程間的相互通信的文章就介紹到這了,更多相關(guān)golang協(xié)程間的相互通信內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • golang避免內(nèi)存溢出的方法

    golang避免內(nèi)存溢出的方法

    內(nèi)存溢出(Memory Overflow)是指程序在運(yùn)行時(shí)超出了分配給它的內(nèi)存限制,從而導(dǎo)致程序異?;虮罎⒌默F(xiàn)象,內(nèi)存溢出的問(wèn)題在任何編程語(yǔ)言中都可能出現(xiàn),Go 語(yǔ)言也不例外,本文給大家介紹了golang是如何解決內(nèi)存溢出的,需要的朋友可以參考下
    2024-09-09
  • Golang中g(shù)oroutine和channel使用介紹深入分析

    Golang中g(shù)oroutine和channel使用介紹深入分析

    一次只做一件事情并不是完成任務(wù)最快的方法,一些大的任務(wù)可以拆解成若干個(gè)小任務(wù),goroutine可以讓程序同時(shí)處理幾個(gè)不同的任務(wù),goroutine使用channel來(lái)協(xié)調(diào)它們的工作,channel允許goroutine互相發(fā)送數(shù)據(jù)并同步,這樣一個(gè)goroutine就不會(huì)領(lǐng)先于另一個(gè)goroutine
    2023-01-01
  • 一文帶你理解Golang中的Time結(jié)構(gòu)

    一文帶你理解Golang中的Time結(jié)構(gòu)

    根據(jù)golang的time包的文檔可以知道,golang的time結(jié)構(gòu)中存儲(chǔ)了兩種時(shí)鐘,一種是Wall?Clocks,一種是Monotonic?Clocks,下面我們就來(lái)簡(jiǎn)單了解一下這兩種結(jié)構(gòu)吧
    2023-09-09
  • 詳解Go如何基于現(xiàn)有的context創(chuàng)建新的context

    詳解Go如何基于現(xiàn)有的context創(chuàng)建新的context

    在?Golang?中,context?包提供了創(chuàng)建和管理上下文的功能,那么在GO語(yǔ)言中如何基于現(xiàn)有的context創(chuàng)建新的context,下面小編就來(lái)和大家詳細(xì)聊聊
    2024-01-01
  • 簡(jiǎn)單聊聊Golang中Flag包的具體使用

    簡(jiǎn)單聊聊Golang中Flag包的具體使用

    flag 包是 Go 語(yǔ)言標(biāo)準(zhǔn)庫(kù)中的一個(gè)包,用于解析命令行參數(shù),這篇文章主要來(lái)和大家簡(jiǎn)單聊聊Golang中Flag包的具體使用,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2023-05-05
  • Golang小數(shù)操作指南之判斷小數(shù)點(diǎn)位數(shù)與四舍五入

    Golang小數(shù)操作指南之判斷小數(shù)點(diǎn)位數(shù)與四舍五入

    這篇文章主要給大家介紹了關(guān)于Golang小數(shù)操作指南之判斷小數(shù)點(diǎn)位數(shù)與四舍五入的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2022-03-03
  • Golang最大遞減數(shù)算法問(wèn)題分析

    Golang最大遞減數(shù)算法問(wèn)題分析

    這篇文章主要介紹了Golang最大遞減數(shù)算法問(wèn)題分析,結(jié)合實(shí)例形式分析了Go語(yǔ)言數(shù)字遍歷與運(yùn)算相關(guān)操作技巧,需要的朋友可以參考下
    2017-01-01
  • Go 計(jì)時(shí)器使用示例全面講解

    Go 計(jì)時(shí)器使用示例全面講解

    這篇文章主要為大家介紹了Go 計(jì)時(shí)器使用示例全面講解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-09-09
  • 盤(pán)點(diǎn)總結(jié)2023年Go并發(fā)庫(kù)有哪些變化

    盤(pán)點(diǎn)總結(jié)2023年Go并發(fā)庫(kù)有哪些變化

    這篇文章主要為大家介紹了2023年Go并發(fā)庫(kù)的變化盤(pán)點(diǎn)總結(jié),有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-12-12
  • go語(yǔ)言里面實(shí)現(xiàn)并發(fā)安全扣減庫(kù)存的幾種方式小結(jié)

    go語(yǔ)言里面實(shí)現(xiàn)并發(fā)安全扣減庫(kù)存的幾種方式小結(jié)

    本文介紹了GORM框架中的幾種高級(jí)查詢技巧,包括隨機(jī)返回?cái)?shù)據(jù)的方法,鎖機(jī)制的使用,Upsert操作,在gorm-gen中使用原生SQL查詢這幾種方法,具有一定的參考價(jià)值,感興趣的可以了解一下
    2026-04-04

最新評(píng)論

怀来县| 宁陵县| 卢龙县| 米泉市| 丰顺县| 沙洋县| 林州市| 五台县| 波密县| 嵊泗县| 芜湖市| 勐海县| 南昌县| 罗定市| 九江市| 济源市| 克拉玛依市| 运城市| 湘乡市| 海盐县| 安达市| 林州市| 贵溪市| 杭锦后旗| 阿拉善盟| 吴桥县| 临西县| 封丘县| 杨浦区| 呈贡县| 辉县市| 鄯善县| 繁峙县| 惠水县| 昌乐县| 荥阳市| 珲春市| 哈密市| 广州市| 南雄市| 公主岭市|