摘要: 一、前言 go語言類似Java JUC包也提供了一些列用于多線程之間進(jìn)行同步的措施,比如低級的同步措施有 鎖、CAS、原子變量操作類。相比Java來說go提供了獨特的基于通道的同步措施。本節(jié)我們先來看看go中CAS操作 二、CAS操作 go中的Cas操作與java中類似,都是借用了CPU提供的原子性指令來實現(xiàn)。
成都創(chuàng)新互聯(lián)公司專注于海安企業(yè)網(wǎng)站建設(shè),響應(yīng)式網(wǎng)站開發(fā),商城開發(fā)。海安網(wǎng)站建設(shè)公司,為海安等地區(qū)提供建站服務(wù)。全流程定制網(wǎng)站建設(shè),專業(yè)設(shè)計,全程項目跟蹤,成都創(chuàng)新互聯(lián)公司專業(yè)和態(tài)度為您提供的服務(wù)
go語言類似Java JUC包也提供了一些列用于多線程之間進(jìn)行同步的措施,比如低級的同步措施有 鎖、CAS、原子變量操作類。相比Java來說go提供了獨特的基于通道的同步措施。本節(jié)我們先來看看go中CAS操作
go中的Cas操作與java中類似,都是借用了CPU提供的原子性指令來實現(xiàn)。CAS操作修改共享變量時候不需要對共享變量加鎖,而是通過類似樂觀鎖的方式進(jìn)行檢查,本質(zhì)還是不斷的占用CPU 資源換取加鎖帶來的開銷(比如上下文切換開銷)。下面一個例子使用CAS來實現(xiàn)計數(shù)器
go中CAS操作具有原子性,在解決多線程操作共享變量安全上可以有效的減少使用鎖所帶來的開銷,但是這是使用cpu資源做交換的。
我簡單列舉了并發(fā)編程的大綱,需要詳細(xì)的私信“555”~~
Go的CSP并發(fā)模型
Go實現(xiàn)了兩種并發(fā)形式。第一種是大家普遍認(rèn)知的:多線程共享內(nèi)存。其實就是Java或者C++等語言中的多線程開發(fā)。另外一種是Go語言特有的,也是Go語言推薦的:CSP(communicating sequential processes)并發(fā)模型。
CSP 是 Communicating Sequential Process 的簡稱,中文可以叫做通信順序進(jìn)程,是一種并發(fā)編程模型,由 Tony Hoare 于 1977 年提出。簡單來說,CSP 模型由并發(fā)執(zhí)行的實體(線程或者進(jìn)程)所組成,實體之間通過發(fā)送消息進(jìn)行通信,這里發(fā)送消息時使用的就是通道,或者叫 channel。CSP 模型的關(guān)鍵是關(guān)注 channel,而不關(guān)注發(fā)送消息的實體。 Go 語言實現(xiàn)了 CSP 部分理論 。
“ 不要以共享內(nèi)存的方式來通信,相反, 要通過通信來共享內(nèi)存。”
Go的CSP并發(fā)模型,是通過 goroutine和channel 來實現(xiàn)的。
goroutine 是Go語言中并發(fā)的執(zhí)行單位。其實就是協(xié)程。
channel是Go語言中各個并發(fā)結(jié)構(gòu)體(goroutine)之前的通信機制。 通俗的講,就是各個goroutine之間通信的”管道“,有點類似于Linux中的管道。
Channel
Goroutine
TCP 和 UDP 服務(wù)端隨處可見,它們基于 TCP/IP 協(xié)議棧,通過網(wǎng)絡(luò)為客戶端提供服務(wù)。在這篇文章中,我將介紹如何使用 Go 語言開發(fā)一個用于返回隨機數(shù)、支持并發(fā)的 TCP 服務(wù)端。對于每一個來自 TCP 客戶端的連接,它都會啟動一個新的 goroutine(輕量級線程)來處理相應(yīng)的請求。
你可以在 GitHub 上找到本項目的源碼:concTcp.go。
這個程序的主要邏輯在 handleConnection 函數(shù)中,具體實現(xiàn)如下:
在 main 函數(shù)的實現(xiàn)部分,每當(dāng) TCP 服務(wù)端收到 TCP 客戶端的連接請求,它都會啟動一個新的 goroutine 來為這個請求提供服務(wù)。
首先, main 確保程序至少有一個命令行參數(shù)。注意,現(xiàn)有代碼并沒有檢查這個參數(shù)是否為有效的 TCP 端口號。不過,如果它是一個無效的 TCP 端口號, net.Listen 就會調(diào)用失敗,并返回一個錯誤信息,類似下面這樣:
net.Listen 函數(shù)用于告訴 Go 接受網(wǎng)絡(luò)連接,因而承擔(dān)了服務(wù)端的角色。它的返回值類型是 net.Conn ,后者實現(xiàn)了 io.Reader 和 io.Writer 接口。此外, main 函數(shù)中還調(diào)用了 rand.Seed 函數(shù),用于初始化隨機數(shù)生成器。最后, for 循環(huán)允許程序一直使用 Accept 函數(shù)來接受 TCP 客戶端的連接請求,并以 goroutine 的方式來運行 handleConnection(c) 函數(shù),處理客戶端的后續(xù)請求。
net.Listen 函數(shù)的第一個參數(shù)定義了使用的網(wǎng)絡(luò)類型,而第二個參數(shù)定義了服務(wù)端監(jiān)聽的地址和端口號。第一個參數(shù)的有效值為 tcp 、 tcp4 、 tcp6 、 udp 、 udp4 、 udp6 、 ip 、 ip4 、 ip6 、 Unix (Unix 套接字)、 Unixgram 和 Unixpacket ,其中: tcp4 、 udp4 和 ip4 只接受 IPv4 地址,而 tcp6 、 udp6 和 ip6 只接受 IPv6 地址。
concTCP.go 需要一個命令行參數(shù),來指定監(jiān)聽的端口號。當(dāng)它開始服務(wù) TCP 客戶端時,你會得到類似下面的輸出:
netstat 的輸出可以確認(rèn) congTCP.go 正在為多個 TCP 客戶端提供服務(wù),并且仍在繼續(xù)監(jiān)聽建立連接的請求:
在上面輸出中,最后一行顯示了有一個進(jìn)程正在監(jiān)聽 8001 端口,這意味著你可以繼續(xù)連接 TCP 的 8001 端口。第一行和第二行顯示了有一個已建立的 TCP 網(wǎng)絡(luò)連接,它占用了 8001 和 62556 端口。相似地,第三行和第四行顯示了有另一個已建立的 TCP 連接,它占用了 8001 和 62554 端口。
下面這張圖片顯示了 concTCP.go 在服務(wù)多個 TCP 客戶端時的輸出:
類似地,下面這張圖片顯示了兩個 TCP 客戶端的輸出(使用了 nc 工具):
你可以在 維基百科上找到更多關(guān)于 nc (即 netcat )的信息。
現(xiàn)在,你學(xué)會了如何用大約 65 行 Go 代碼來開發(fā)一個生成隨機數(shù)、支持并發(fā)的 TCP 服務(wù)端,這真是太棒了!如果你想要讓你的 TCP 服務(wù)端執(zhí)行別的任務(wù),只需要修改 handleConnection 函數(shù)即可。
via:
作者:Mihalis Tsoukalos選題:lkxed譯者:lkxed校對:wxy
網(wǎng)頁題目:go語言編程并發(fā)通信 go語言 并發(fā)
網(wǎng)頁網(wǎng)址:http://www.rwnh.cn/article42/dosihhc.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站改版、網(wǎng)站收錄、企業(yè)網(wǎng)站制作、全網(wǎng)營銷推廣、云服務(wù)器、自適應(yīng)網(wǎng)站
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)