1. 程式人生 > >Golang從入門到精通(十八):Golang併發程式設計之Goroutine

Golang從入門到精通(十八):Golang併發程式設計之Goroutine

程序,執行緒,並行和併發

一個應用程式是執行在機器上的一個程序;程序是一個執行在自己記憶體地址空間裡的獨立執行體。一個程序由一個或多個作業系統執行緒組成,這些執行緒其實是共享同一個記憶體地址空間的一起工作的執行體。幾乎所有’正式’的程式都是多執行緒的,以便讓使用者或計算機不必等待,或者能夠同時服務多個請求(如 Web 伺服器),或增加效能和吞吐量(例如,通過對不同的資料集並行執行程式碼)。

一個併發程式可以在一個處理器或者核心上使用多個執行緒來執行任務,但是隻有在同一個程式在某一個時間點在多個些處理核心或處理器上同時執行的任務才是真正的並行。

並行是一種通過使用多處理器以提高速度的能力。所以併發程式可以是並行的,也可以不是。

公認的使用多執行緒的應用最主要的問題是記憶體中的資料共享,它們會被多執行緒以無法預知的方式進行操作,導致一些無法重現或者隨機的結果(稱作競態)。

Go中,應用程式併發處理的部分被稱作 goroutines(go協程),它可以進行更有效的併發運算。在協程和作業系統執行緒之間並無一對一的關係:協程是根據一個或多個執行緒的可用性,對映(多路複用,執行於)在它們之上的;協程排程器在 Go 執行時很好的完成了這個工作。

Goroutine簡介

Go語言中有個概念叫做goroutine, 這類似我們熟知的執行緒,但是更加輕量級。

我們先來看一個沒有併發的例子,序列地去執行兩次loop函式:

package
main import "fmt" func loop() { for i := 0; i < 10; i++ { fmt.Printf("%d ", i) } } func main() { loop() loop() }

這裡的輸出是顯而易見的,是0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9

現在我們把一個loop放在一個goroutine裡跑,我們可以使用關鍵字go來定義並啟動一個goroutine,main()函式變為:

func main() {
    go loop()
    loop()
}

就加了一個 go 關鍵字 ,輸入就變成了:

0 1 2 3 4 5 6 7 8 9

可是為什麼只輸出了一趟呢?明明我們主線跑了一趟,也開了一個goroutine來跑一趟啊。

原來,在goroutine還沒來得及跑loop的時候,主函式已經退出了。

如何讓goroutine告訴主執行緒我執行完畢了?使用一個通道來告訴主執行緒即可。

無緩衝的通道在取訊息和存訊息的時候都會掛起當前的goroutine,除非另一端已經準備好。如果不用通道來阻塞主線的話,主執行緒就會過早跑完,loop執行緒都沒有機會執行。

本關卡需要強調的是,無緩衝的通道永遠不會儲存資料,只負責資料的流通。體現在:

  1. 從無緩衝通道取資料,必須要有資料流進來才可以,否則當前線阻塞
  2. 資料流入無緩衝通道, 如果沒有其他goroutine來拿走這個資料,那麼當前線阻塞

現在這裡給出程式碼,具體Channel的原理和使用在本實訓下一關卡Go語言Channel中詳細講解。

var complete chan int = make(chan int)

func loop() {
    for i := 0; i < 10; i++ {
        fmt.Printf("%d ", i)
    }

    complete <- 0 // 執行完畢了,發個訊息
}


func main() {
    go loop()
    <- complete // 直到執行緒跑完, 取到訊息. main在此阻塞住
}

相關推薦

Golang入門精通Golang併發程式設計Goroutine

程序,執行緒,並行和併發 一個應用程式是執行在機器上的一個程序;程序是一個執行在自己記憶體地址空間裡的獨立執行體。一個程序由一個或多個作業系統執行緒組成,這些執行緒其實是共享同一個記憶體地址空間的一起工作的執行體。幾乎所有’正式’的程式都是多執行緒的,以便讓使

Golang入門精通Golang方法

方法 在 Go 語言中有一個概念和函式極其相似,叫做方法 。Go 語言的方法其實是作用在接收者(receiver)上的一個函式,接收者是某種非內建型別的變數。因此方法是一種特殊型別的函式。 接收者型別可以是(幾乎)任何型別,不僅僅是結構體型別:任何型別都可以

Golang入門精通Golang併發程式設計Channel

Go語言併發模型 Go 語言中使用了CSP模型來進行執行緒通訊,準確說,是輕量級執行緒goroutine之間的通訊。CSP模型和Actor模型類似,也是由獨立的,併發執行的實體所構成,實體之間也是通過傳送訊息進行通訊的。 Actor模型和CSP模型區別 A

通證經濟大局觀邊際量續篇使用者需求

現在的區塊鏈專案多如牛毛,專案與專案之間不管多麼不同,本質上都是競爭關係,競爭的標的就是使用者資金和使用者注意力。 使用者選擇專案,往往是哪個熱門就選哪個。而熱門的前提,是這個專案必須有一批忠實的早期使用者。專案靠他們奠定基礎、宣傳推廣、貢獻金錢精力才能變得火熱。 所以,專案方通常會

Spring Boot 初級入門教程 —— 整合 MyBatis 另外一種開發方式

在前面兩篇文章《Spring Boot 初級入門教程(十五) —— 整合 MyBatis》和《Spring Boot 初級入門教程(十七) —— 通過 Oracle 資料庫測試已整合 MyBatis(附原始碼)》中,介紹瞭如何在 SpringBoot 中整合 MyBatis 以及通過 MySQL

Unity Shader入門精要筆記透明度混合

本系列文章由Aimar_Johnny編寫,歡迎轉載,轉載請標明出處,謝謝。 前面章節介紹過,透明度混合是實現了真正的半透效果。它會以當前片元透明度作為混合因子,與已經儲存在顏色緩衝區中的顏色進行混合,得到新的顏色。同時要關掉深度寫入,小心物體的渲染順序。 為了進行

Spring Boot入門系列整合mybatis,使用註解的方式實現增刪改查

之前介紹了Spring Boot 整合mybatis 使用xml配置的方式實現增刪改查,還介紹了自定義mapper 實現複雜多表關聯查詢。雖然目前 mybatis 使用xml 配置的方式 已經極大減輕了配置的複雜度,支援 generator 外掛 根據表結構自動生成實體類、配置檔案和dao層程式碼,減輕很大一

Python+Selenium筆記持續集成jenkins

每次 repo adt webdriver 測試的 ews equal unit pcl (一)安裝xmlrunner 使用Jenkins執行測試時,測試代碼中會用到這個模塊。 pip install xmlrunner (二)安裝jenkins (1) 下載jeki

用Vue來實現音樂播放器右側快速入口點擊高亮

為我 UC 沒有 short cut this 必須 左右 png 問題一:當我們點擊右側快速入口的時候 被點擊的地方高亮 首先我們要知道右側快速入口是為什麽高亮??因為當watch()監控到scrollY的變化了的時候 將scrollY的值和listHeight相比較

java基礎學習總結切勿用普通for迴圈遍歷LinkedList

ArrayList與LinkedList的普通for迴圈遍歷 對於大部分Java程式設計師朋友們來說,可能平時使用得最多的List就是ArrayList,對於ArrayList的遍歷,一般用如下寫法: public static void main(String[] args) {

javaweb學習筆記JDBC4

DbUtils元件 O/R Mapping: 廣義上,ORM指的是面向物件的物件模型和關係型資料庫的資料結構之間的相互轉換。 狹義上,ORM可以被認為是,基於關係型資料庫的資料儲存,實現一個虛擬的面向物件的資料訪問介面。理想情況下,基於這樣一個面向物件的介面,持久化一個OO物件應該不

大資料Hive元資料配置、常見屬性配置、資料型別與資料轉換

一、Hive元資料配置到MySQL當中         為什麼要把Hive的元資料配置到MySql中?我們可以使用多個客戶端連線linux系統並且都嘗試啟動Hive,可以發現在啟動第二個Hive客戶端的時候發生報錯了。   

Java併發(十八):阻塞佇列BlockingQueue BlockingQueue阻塞佇列詳解 二叉堆(一) 圖文解析 和 C語言的實現 多執行緒程式設計:阻塞、併發佇列的使用總結 Java併發程式設計:阻塞佇列 java阻塞佇列 BlockingQueue阻塞佇列詳解

阻塞佇列(BlockingQueue)是一個支援兩個附加操作的佇列。 這兩個附加的操作是:在佇列為空時,獲取元素的執行緒會等待佇列變為非空。當佇列滿時,儲存元素的執行緒會等待佇列可用。 阻塞佇列常用於生產者和消費者的場景,生產者是往佇列裡新增元素的執行緒,消費者是從佇列裡拿元素的執行緒。阻塞佇列就是生產者

機器學習筆記TensorFlow實戰影象資料處理

1 - 引言 之前我們介紹了通過卷積神經網路可以給影象識別技術帶來突破性的進展,現在我們從影象的預處理這個角度來繼續提升我們影象識別的準確率。 輸入的預處理需要使用TFRecord格式來同一不同的原始資料格式,並且更加有效的管理不同的屬性。 並且TensorFlow支援影象處理函式,

linux系列locate命令

1、命令格式:   locate [選擇引數] [樣式] 2、命令功能: locate指令和find找尋檔案的功能類似,但locate是透過update程式將硬碟中的所有檔案和目錄資料先建立一個索引資料庫,在 執行loacte時直接找該索引,查詢速度會較快,索引資料庫一般是

Java併發執行緒池實現原理 Java併發阻塞佇列BlockingQueue Java併發阻塞佇列BlockingQueue Java併發程式設計執行緒池的使用

一、總覽 執行緒池類ThreadPoolExecutor的相關類需要先了解:  (圖片來自:https://javadoop.com/post/java-thread-pool#%E6%80%BB%E8%A7%88) Executor:位於最頂層,只有一個 execute(Runnab

opencv學習影象梯度

程式程式碼: #匯入cv模組 # -*- coding=utf-8 -*- import cv2 as cv import numpy as np #lapalian運算元 def lapalian_demo(image): # dst=cv.Laplacian(image,cv.CV

演算法題搜狗19年校招程式設計——找區間

注:筆試時並沒有AC,線下修改後可以輸出示例結果。 問題:從一個序列中找出所有包含全部數字的最小索引區間,若有多個則按出現的順序輸出。 輸入輸出示例: 輸入:1 1 3 4 6 6 5 1 1 3 3 輸出:[2,7] [3,8] [4,9] 分析:先用一個list

Spring Security5.9 Post Processing Configured Objects

Spring Security’s Java Configuration does not expose every property of every object that it configures. This simplifies the configuration for a majority of

Spring Boot + Spring Cloud 實現許可權管理系統 後端篇服務註冊和發現Consul

什麼是 Consul Consul 是 HashiCorp 公司推出的開源工具,用於實現分散式系統的服務發現與配置。與其它分散式服務註冊與發現的方案,Consul 的方案更“一站式”,內建了服務註冊與發現框架、分佈一致性協議實現、健康檢查、Key/Value 儲存、多資料中心方案,不再需要依賴其它工具(比如