新聞中心
通過上一節(jié)《 Go語言goroutine》的學(xué)習(xí),關(guān)鍵字 go 的引入使得在Go語言中并發(fā)編程變得簡單而優(yōu)雅,但我們同時也應(yīng)該意識到并發(fā)編程的原生復(fù)雜性,并時刻對并發(fā)中容易出現(xiàn)的問題保持警惕。

創(chuàng)新互聯(lián)專注為客戶提供全方位的互聯(lián)網(wǎng)綜合服務(wù),包含不限于做網(wǎng)站、網(wǎng)站設(shè)計、江寧網(wǎng)絡(luò)推廣、微信平臺小程序開發(fā)、江寧網(wǎng)絡(luò)營銷、江寧企業(yè)策劃、江寧品牌公關(guān)、搜索引擎seo、人物專訪、企業(yè)宣傳片、企業(yè)代運營等,從售前售中售后,我們都將竭誠為您服務(wù),您的肯定,是我們最大的嘉獎;創(chuàng)新互聯(lián)為所有大學(xué)生創(chuàng)業(yè)者提供江寧建站搭建服務(wù),24小時服務(wù)熱線:18980820575,官方網(wǎng)址:www.cdcxhl.com
事實上,不管是什么平臺,什么編程語言,不管在哪,并發(fā)都是一個大話題。并發(fā)編程的難度在于協(xié)調(diào),而協(xié)調(diào)就要通過交流,從這個角度看來,并發(fā)單元間的通信是最大的問題。
在工程上,有兩種最常見的并發(fā)通信模型:共享數(shù)據(jù)和消息。
共享數(shù)據(jù)是指多個并發(fā)單元分別保持對同一個數(shù)據(jù)的引用,實現(xiàn)對該數(shù)據(jù)的共享。被共享的數(shù)據(jù)可能有多種形式,比如內(nèi)存數(shù)據(jù)塊、磁盤文件、網(wǎng)絡(luò)數(shù)據(jù)等。在實際工程應(yīng)用中最常見的無疑是內(nèi)存了,也就是常說的共享內(nèi)存。
先看看我們在C語言中通常是怎么處理線程間數(shù)據(jù)共享的,代碼如下所示。
#include#include #include void *count(); pthread_mutex_t mutex1 = PTHREAD_MUTEX_INITIALIZER; int counter = 0; int main() { int rc1, rc2; pthread_t thread1, thread2; /* 創(chuàng)建線程,每個線程獨立執(zhí)行函數(shù)functionC */ if((rc1 = pthread_create(&thread1, NULL, &count, NULL))) { printf("Thread creation failed: %d\n", rc1); } if((rc2 = pthread_create(&thread2, NULL, &count, NULL))) { printf("Thread creation failed: %d\n", rc2); } /* 等待所有線程執(zhí)行完畢 */ pthread_join( thread1, NULL); pthread_join( thread2, NULL); exit(0); } void *count() { pthread_mutex_lock( &mutex1 ); counter++; printf("Counter value: %d\n",counter); pthread_mutex_unlock( &mutex1 ); }
現(xiàn)在我們嘗試將這段C語言代碼直接翻譯為Go語言代碼,代碼如下所示。
package main
import (
"fmt"
"runtime"
"sync"
)
var counter int = 0
func Count(lock *sync.Mutex) {
lock.Lock()
counter++
fmt.Println(counter)
lock.Unlock()
}
func main() {
lock := &sync.Mutex{}
for i := 0; i < 10; i++ {
go Count(lock)
}
for {
lock.Lock()
c := counter
lock.Unlock()
runtime.Gosched()
if c >= 10 {
break
}
}
}在上面的例子中,我們在 10 個 goroutine 中共享了變量 counter。每個 goroutine 執(zhí)行完成后,會將 counter 的值加 1。因為 10 個 goroutine 是并發(fā)執(zhí)行的,所以我們還引入了鎖,也就是代碼中的 lock 變量。每次對 n 的操作,都要先將鎖鎖住,操作完成后,再將鎖打開。
在 main 函數(shù)中,使用 for 循環(huán)來不斷檢查 counter 的值(同樣需要加鎖)。當其值達到 10 時,說明所有 goroutine 都執(zhí)行完畢了,這時主函數(shù)返回,程序退出。
事情好像開始變得糟糕了。實現(xiàn)一個如此簡單的功能,卻寫出如此臃腫而且難以理解的代碼。想象一下,在一個大的系統(tǒng)中具有無數(shù)的鎖、無數(shù)的共享變量、無數(shù)的業(yè)務(wù)邏輯與錯誤處理分支,那將是一場噩夢。這噩夢就是眾多 C/ C++ 開發(fā)者正在經(jīng)歷的,其實 Java 和 C# 開發(fā)者也好不到哪里去。
Go語言既然以并發(fā)編程作為語言的最核心優(yōu)勢,當然不至于將這樣的問題用這么無奈的方式來解決。Go語言提供的是另一種通信模型,即以消息機制而非共享內(nèi)存作為通信方式。
消息機制認為每個并發(fā)單元是自包含的、獨立的個體,并且都有自己的變量,但在不同并發(fā)單元間這些變量不共享。每個并發(fā)單元的輸入和輸出只有一種,那就是消息。這有點類似于進程的概念,每個進程不會被其他進程打擾,它只做好自己的工作就可以了。不同進程間靠消息來通信,它們不會共享內(nèi)存。
Go語言提供的消息通信機制被稱為 channel,關(guān)于 channel 的介紹將在后續(xù)的學(xué)習(xí)中為大家講解。
分享文章:創(chuàng)新互聯(lián)GO教程:Go語言并發(fā)通信
文章分享:http://fisionsoft.com.cn/article/dhcjcoj.html


咨詢
建站咨詢
