前面已經說過通道的簡介以及具體使用,那麼通道是如何收發資料的,今天就和大家聊下。
通道傳送資料的格式
通道的傳送使用特殊的操作符<-,將資料通過通道傳送的格式為:
通道變數 <- 值示例:
使用 make 建立乙個通道後,就可以使用<-向通道傳送資料,**如下:
// 建立乙個空介面通道
ch :=
make
(chan
inte***ce
)// 將0放入通道中
ch <-
0// 將hello字串放入通道中
ch <-
"hello"
傳送資料失敗持續阻塞直到資料被接收
把資料往通道中傳送時,如果接收方一直都沒有接收,那麼傳送操作將持續阻塞。go 程式執行時能智慧型地發現一些永遠無法傳送成功的語句並做出提示,**如下:
package main
func
main()
執行**,報錯:
fatal error
: all goroutines are asleep - deadlock!
解析:
執行時發現所有的 goroutine(包括main)都處於等待 goroutine。也就是說所有 goroutine 中的 channel 並沒有形成傳送和接收對應的**。
通道接收同樣使用<-操作符,通道接收有如下特性:
通道的收發操作在不同的兩個 goroutine 間進行。
由於通道的資料在沒有接收方處理時,資料傳送方會持續阻塞,因此通道的接收必定在另外乙個 goroutine 中進行。
接收將持續阻塞直到傳送方傳送資料。
如果接收方接收時,通道中沒有傳送方傳送資料,接收方也會發生阻塞,直到傳送方傳送資料為止。
每次接收乙個元素。
通道一次只能接收乙個資料元素。
接收資料有以下 幾種寫法:
阻塞接收資料
阻塞模式接收資料時,將接收變數作為<-操作符的左值,格式如下:
data := <-ch執行該語句時將會阻塞,直到接收到資料並賦值給 data 變數。
非阻塞接收資料
使用非阻塞方式從通道接收資料時,語句不會發生阻塞,格式如下:
data, ok := <-ch解析:
非阻塞的通道接收方法可能造成高的 cpu 占用,因此使用非常少。如果需要實現接收超時檢測,可以配合 select 和計時器 channel 進行,可以參見後面的內容。
接收任意資料,忽略接收的資料
阻塞接收資料後,忽略從通道返回的資料,格式如下:
<-ch執行該語句時將會發生阻塞,直到接收到資料,但接收到的資料會被忽略。這個方式實際上只是通過通道在 goroutine 間阻塞收發實現併發同步。
使用通道做併發同步的寫法,示例:
package main
import
("fmt"
)func
main()
()fmt.
println
("wait goroutine"
)// 等待匿名goroutine
<-ch
fmt.
println
("all done"
)}
執行結果如下:
wait goroutine
start goroutine
exit goroutine
all done
解析:
4.迴圈接收
通道的資料接收可以借用 for range 語句進行多個元素的接收操作,格式如下:
for data :=
range ch
通道 ch 是可以進行遍歷的,遍歷的結果就是接收到的資料。資料型別就是通道的資料型別。通過 for 遍歷獲得的變數只有乙個,即上面例子中的 data。
遍歷通道資料
使用 for 從通道中接收資料:
package main
import
("fmt"
"time"
)func
main()
}()// 遍歷接收通道資料
for data :=
range ch
}}
執行**,輸出如下:
321
0
解析: LWIP 資料接收和傳送
在znyq的sdk例程中,main中主迴圈傳送接收,其中接收為 xemacif input echo netif 查詢xemacit input 函式裡 在echo.c裡有receive的處理函式recv callback 資料接收 tcp recved tpcb,p len 其中的tcp recv...
socket傳送和接收資料
1 sendbuf sendtext sendstream 幾乎所有的通訊控制項都會提供上面的3個方法。首先看看sendbuf function tcustomwinsocket.sendbuf var buf count integer integer varerrorcode integer b...
json資料傳送和接收
後面這兩部很重要,我看網上很多都是使用xmlhttp.send username username password 這樣接收還要解析一番感覺還是直接傳送以下格式的好些 通過eval 方法將json格式的字串轉化為js物件,並進行解析獲取內容 var result eval text if resu...