golang線程同步,golang 異步

本文目錄一覽:

golang多線程簡單邏輯

實現指定個核心最大化使用,比如核心總數減一。

必要的庫。

要使用的cpu數量,建議不全使用。

建立管道。

聲明使用的cpu數。

建立互斥關係,本例中主要為了實現所有線程執行完後再執行後續程序。

創建cpu數減1個線程

後面每個任務結束時要done一個wg,這裡根據具體情況加,是循環就在每個循環里加,保證後面能全部done即可

沒有緩衝的、阻塞式的往管道傳遞字符串。

Wait是等所有線程都執行完,即增加的數字被全done掉。

關閉管道。

假設已有的函數是ReadLogs,在它的基礎上加個Wg加函數名的新函數,我覺得這種方式不改變原有的,比較舒服。

大意是:循環從管道讀取字符串,讀不到了就跳出循環。

每個ReadLogs()之後加一個wg.Done(),相當於計數減一。

ReadLogs()就是要執行的任務,不再解釋。

就是開指定個線程。

管道阻塞傳值。

wg同步。

WgReadLogs循環接收。

Go語言WaitGroup使用時需要注意什麼

WaitGroup在go語言中,用於線程同步,單從字面意思理解,wait等待的意思,group組、團隊的意思,WaitGroup就是指等待一組,等待一個系列執行完成後才會繼續向下執行。Golang 中的 WaitGroup 一直是同步 goroutine 的推薦實踐。自己用了兩年多也沒遇到過什麼問題。

直到最近的一天同事扔過來一段奇怪的代碼:

好了,到這裡終於解決了,以上就是關於Go語言WaitGroup使用時需要注意的一些坑,希望本文中提到的這些問題對大家學習或者使用Go語言的時候能有所幫助,如果有疑問大家可以留言交流。

怎樣理解golang的異步

同步的意思是,後一條指令必須要等待上一條指令執行完成後,才開始運行;異步呢就是,上一條指令啟動後,就在“另一個維度”運行了,和下一條指令好像是同時運行的,更為生動的說法,我照搬一下一個百度知道的神比喻:

你給了狗一個包子,然後就走開做別的事去了,過後狗追過來對你說了聲謝謝,

或者咬了你一口說,包子有毒。這是異步。

同樣你給了狗一個包子後,看着狗把包子吃完,並對你搖尾巴,這個期間你一點別的

事都不做,就等着狗吃完包子。 這是同步。

用你問題中的代碼,可以理解為:

你再給了狗一個包子,然後就呆在原地除了等狗啥都不做,過會兒狗追過來對你說了聲謝謝,你再心滿意足地繼續做自己的事情,這就是將異步阻塞後變成的同步。

所以呢,同步和阻塞還是有那麼些聯繫的(如果你把它們揉在一起的話)。

再說回 golang,其實你代碼中,也就兩個 go 語句是達到這個效果了的,但相對於 fmt.Println(“繼續執行”) 以及後面的代碼來說,前兩條語句還是異步執行的,並且它不像 javascript 那樣只是單線程工作(並發),golang 協程是可以多個同時工作的(並行)

go語言無緩衝的channel

無緩衝的通道(unbuffered channel)是指在接收前沒有能力保存任何值的通道。

這種類型的通道要求發送goroutine和接收goroutine同時準備好,才能完成發送和接收操作。否則,通道會導致先執行發送或接收操作的 goroutine 阻塞等待。

這種對通道進行發送和接收的交互行為本身就是同步的。其中任意一個操作都無法離開另一個操作單獨存在。

阻塞:由於某種原因數據沒有到達,當前協程(線程)持續處於等待狀態,直到條件滿足,才接觸阻塞。

同步:在兩個或多個協程(線程)間,保持數據內容一致性的機制。

下圖展示兩個 goroutine 如何利用無緩衝的通道來共享一個值:

在第 1 步,兩個 goroutine 都到達通道,但哪個都沒有開始執行發送或者接收。

在第 2 步,左側的 goroutine 將它的手伸進了通道,這模擬了向通道發送數據的行為。這時,這個 goroutine 會在通道中被鎖住,直到交換完成。

在第 3 步,右側的 goroutine 將它的手放入通道,這模擬了從通道里接收數據。這個 goroutine 一樣也會在通道中被鎖住,直到交換完成。

在第 4 步和第 5 步,進行交換,並最終,在第 6 步,兩個 goroutine 都將它們的手從通道里拿出來,這模擬了被鎖住的 goroutine 得到釋放。兩個 goroutine 現在都可以去做別的事情了。

如果沒有指定緩衝區容量,那麼該通道就是同步的,因此會阻塞到發送者準備好發送和接收者準備好接收。

無緩衝channel: —— 同步通信

golang的線程模型——GMP模型

內核線程(Kernel-Level Thread ,KLT)

輕量級進程(Light Weight Process,LWP):輕量級進程就是我們通常意義上所講的線程,由於每個輕量級進程都由一個內核線程支持,因此只有先支持內核線程,才能有輕量級進程

用戶線程與系統線程一一對應,用戶線程執行如lo操作的系統調用時,來回切換操作開銷相對比較大

多個用戶線程對應一個內核線程,當內核線程對應的一個用戶線程被阻塞掛起時候,其他用戶線程也阻塞不能執行了。

多對多模型是可以充分利用多核CPU提升運行效能的

go線程模型包含三個概念:內核線程(M),goroutine(G),G的上下文環境(P);

GMP模型是goalng特有的。

P與M一般是一一對應的。P(上下文)管理着一組G(goroutine)掛載在M(內核線程)上運行,圖中左邊藍色為正在執行狀態的goroutine,右邊為待執行狀態的goroutiine隊列。P的數量由環境變量GOMAXPROCS的值或程序運行runtime.GOMAXPROCS()進行設置。

當一個os線程在執行M1一個G1發生阻塞時,調度器讓M1拋棄P,等待G1返回,然後另起一個M2接收P來執行剩下的goroutine隊列(G2、G3…),這是golang調度器厲害的地方,可以保證有足夠的線程來運行剩下所有的goroutine。

當G1結束後,M1會重新拿回P來完成,如果拿不到就丟到全局runqueue中,然後自己放到線程池或轉入休眠狀態。空閑的上下文P會周期性的檢查全局runqueue上的goroutine,並且執行它。

另一種情況就是當有些P1太閑而其他P2很忙碌的時候,會從其他上下文P2拿一些G來執行。

詳細可以翻看下方第一個參考鏈接,寫得真好。

最後用大佬的總結來做最後的收尾————

Go語言運行時,通過核心元素G,M,P 和 自己的調度器,實現了自己的並發線程模型。調度器通過對G,M,P的調度實現了兩級線程模型中操作系統內核之外的調度任務。整個調度過程中會在多種時機去觸發最核心的步驟 “一整輪調度”,而一整輪調度中最關鍵的部分在“全力查找可運行G”,它保證了M的高效運行(換句話說就是充分使用了計算機的物理資源),一整輪調度中還會涉及到M的啟用停止。最後別忘了,還有一個與Go程序生命周期相同的系統監測任務來進行一些輔助性的工作。

淺析Golang的線程模型與調度器

Golang CSP並發模型

Golang線程模型

原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-hant/n/206743.html

(0)
打賞 微信掃一掃 微信掃一掃 支付寶掃一掃 支付寶掃一掃
小藍的頭像小藍
上一篇 2024-12-08 14:17
下一篇 2024-12-08 14:17

相關推薦

  • 使用Golang調用Python

    在現代軟件開發中,多種編程語言的協作是相當普遍的。其中一種使用場景是Golang調用Python,這使得在使用Python庫的同時,可以利用Golang的高性能和強大並發能力。這篇…

    編程 2025-04-29
  • Python線程等待指南

    本文將從多個方面詳細講解Python線程等待的相關知識。 一、等待線程結束 在多線程編程中,經常需要等待線程執行完畢再進行下一步操作。可以使用join()方法實現等待線程執行完畢再…

    編程 2025-04-29
  • 使用Golang創建黑色背景圖片的方法

    本文將從多個方面介紹使用Golang創建黑色背景圖片的方法。 一、安裝必要的代碼庫和工具 在開始創建黑色背景圖片之前,我們需要先安裝必要的代碼庫和工具: go get -u git…

    編程 2025-04-29
  • Python兩個線程交替打印1到100

    這篇文章的主題是關於Python多線程的應用。我們將會通過實際的代碼,學習如何使用Python兩個線程交替打印1到100。 一、創建線程 在Python中,我們可以使用Thread…

    編程 2025-04-28
  • ROS線程發布消息異常解決方法

    針對ROS線程發布消息異常問題,我們可以從以下幾個方面進行分析和解決。 一、檢查ROS代碼是否正確 首先,我們需要檢查ROS代碼是否正確。可能會出現的問題包括: 是否正確初始化RO…

    編程 2025-04-28
  • Python線程池並發爬蟲

    Python線程池並發爬蟲是實現多線程爬取數據的常用技術之一,可以在一定程度上提高爬取效率和數據處理能力。本文將從多個方面對Python線程池並發爬蟲做詳細的闡述,包括線程池的實現…

    編程 2025-04-27
  • 線程池中的一個線程異常了會被怎麼處理

    本文將從以下幾個方面對線程池中的一個線程異常了會被怎麼處理進行詳細闡述:異常的類型、如何捕獲異常、異常的處理方式。 一、異常的類型 在線程池中,可以出現多種類型的異常,例如線程執行…

    編程 2025-04-27
  • 線程池的七個參數

    在多線程編程中,線程池是一種非常重要的編程模型,可以解決線程創建銷毀的開銷問題,提高程序的效率。在使用線程池時,需要對其七個參數進行配置,以達到最佳性能。下面將從多個方面詳細闡述線…

    編程 2025-04-25
  • Golang中使用strings.Split函數進行字符串分割的方法

    一、Split函數的基本用法 字符串是編程中常見的數據類型,它們可以在程序中被處理、存儲和傳輸。在Go語言中,字符串也是一個基本的數據類型,而strings包提供了一些操作字符串的…

    編程 2025-04-23
  • Java DelayQueue:實現延遲任務的線程安全隊列

    一、DelayQueue的概述 Java的DelayQueue 是一個阻塞隊列隊列,主要用來實現對延遲任務的調度,也就是在指定的時間之後才能夠取出任務來執行。該隊列中保存的元素都必…

    編程 2025-04-23

發表回復

登錄後才能評論