go語(yǔ)言多協(xié)程讀取數(shù)據(jù) go 協(xié)程 返回值

channel使用

【譯文】 原文地址

成都創(chuàng)新互聯(lián)是一家專(zhuān)業(yè)提供克東企業(yè)網(wǎng)站建設(shè),專(zhuān)注與網(wǎng)站設(shè)計(jì)、成都網(wǎng)站建設(shè)、H5網(wǎng)站設(shè)計(jì)、小程序制作等業(yè)務(wù)。10年已為克東眾多企業(yè)、政府機(jī)構(gòu)等服務(wù)。創(chuàng)新互聯(lián)專(zhuān)業(yè)網(wǎng)絡(luò)公司優(yōu)惠進(jìn)行中。

channel是Go語(yǔ)言的一個(gè)標(biāo)志性特性,為go協(xié)程之間的數(shù)據(jù)交互提供一種非常強(qiáng)大的方式,而不需要使用鎖機(jī)制。

本文將討論channel的兩個(gè)重要屬性,一個(gè)是控制協(xié)程間數(shù)據(jù)發(fā)送和接收,以及對(duì)channel本身控制。

首先討論下關(guān)閉的channel特性。一旦channel被關(guān)閉之后,就不能再繼續(xù)發(fā)送數(shù)據(jù)給該channel,但是還是可以繼續(xù)接收channel中的數(shù)據(jù)。如下所示:

output:

上述例子顯示即使ch在for循環(huán)之前已經(jīng)關(guān)閉,但還是可以正常的讀取緩存中的true值,讀完之后ok就會(huì)被賦值為false表示channel已經(jīng)關(guān)閉,而且value值為對(duì)應(yīng)channel類(lèi)型bool的默認(rèn)零值false。只要不停地從關(guān)閉的channel接收,就會(huì)無(wú)限的返回默認(rèn)值和false??梢詫or循環(huán)次數(shù)改大點(diǎn)試試即可驗(yàn)證。

通過(guò)以上例子可以發(fā)現(xiàn),關(guān)閉的channel可以繼續(xù)接收讀取操作,這種特征是有用的。在使用range讀取帶緩存的channel時(shí)就會(huì)用到,一旦channel關(guān)閉,讀取完緩存中數(shù)據(jù)就會(huì)停止接收數(shù)據(jù)退出。

將前面的例子改為如下:

output:

上面的例子就沒(méi)有false打出來(lái)了。正好是寫(xiě)入channel里面的兩個(gè)值。

channel與select結(jié)合更能發(fā)揮出其作用,讓我們看一個(gè)例子:

上面的例子,因?yàn)閒inish在主協(xié)程中發(fā)送之后,馬上就會(huì)在select中接收,并執(zhí)行done.Done()。主協(xié)程wait馬上會(huì)退出整個(gè)程序就結(jié)束。但是這里面存在一個(gè)問(wèn)題,如果在select中沒(méi)有添加finish case的話(huà),主協(xié)程就永遠(yuǎn)發(fā)送不了數(shù)據(jù)到finish這個(gè)channel,因?yàn)槠洳粠Ь彺?。這里就可以通過(guò)將finish改成帶緩存的channel,或者可以讓select中的finish不會(huì)阻塞。

但是出現(xiàn)多個(gè)協(xié)程都在接收f(shuō)inish通道中的數(shù)據(jù)的話(huà),就需要發(fā)送對(duì)應(yīng)協(xié)程數(shù)量的值到channel中才能解決上面的問(wèn)題。但是具體有多少個(gè)協(xié)程這往往是不好確定的,因?yàn)橛行﹨f(xié)程可能是程序其他部分創(chuàng)建的。一個(gè)比較好的選擇就是通過(guò)使用關(guān)閉通道的方法來(lái)實(shí)現(xiàn)各協(xié)程能正常接收并結(jié)束。

如下所示:

output:

上面的例子就是使用了關(guān)閉的channel可以無(wú)限地接收到反饋數(shù)據(jù)。這樣每個(gè)協(xié)程都能從finish通道中讀到關(guān)閉信息并執(zhí)行done.Done()使得主協(xié)程wait能退出。并且不需要關(guān)注多少個(gè)協(xié)程數(shù),就能正確的讓所有協(xié)程讀到finish通道信息。

channel的這個(gè)特性,可以讓程序員無(wú)需關(guān)注后臺(tái)具體執(zhí)行協(xié)程個(gè)數(shù),確保每個(gè)協(xié)程都能接收到通道關(guān)閉信息,而無(wú)需擔(dān)心死鎖問(wèn)題。

通過(guò)上面的例子我們也發(fā)現(xiàn)每個(gè)協(xié)程并不需要從通道中讀取對(duì)應(yīng)類(lèi)型的數(shù)據(jù),只需讓接收操作能執(zhí)行就行,讓select不被阻塞。所以可以使用空結(jié)構(gòu)體類(lèi)型,我們可以改成如下:

這里我們只關(guān)注通道是否關(guān)閉這個(gè)信號(hào),而不需要關(guān)注通道里面的數(shù)據(jù),所以可使用空結(jié)構(gòu)體類(lèi)型通道。

第二個(gè)要討論的是nil通道:如果定義了一個(gè)channel變量沒(méi)有被初始化,或者被賦值為nil,那么該chennel總是處于阻塞狀態(tài)。如下所示:

執(zhí)行結(jié)果為:

因?yàn)閏hannel為nil無(wú)法發(fā)送數(shù)據(jù),當(dāng)然也不能接收數(shù)據(jù):

這個(gè)似乎看起來(lái)不是很重要,但是如果你想使用關(guān)閉channel來(lái)等待多個(gè)channel關(guān)閉的話(huà),這個(gè)特性就有用處了。先看下面的例子:

WaitMany()函數(shù)看起來(lái)好像是一個(gè)等待通道a和b關(guān)閉的好方法,但是存在一個(gè)問(wèn)題。假設(shè)a通道先關(guān)閉,case -a就會(huì)變成非阻塞。因?yàn)閎closed還是false,程序就會(huì)進(jìn)入到一個(gè)死循環(huán)當(dāng)中,導(dǎo)致b通道永遠(yuǎn)無(wú)法確認(rèn)關(guān)閉。

一個(gè)安全的方法就是使用nil通道總是阻塞的特點(diǎn),如下所示:

上面的例子我們?cè)赪aitMany函數(shù)當(dāng)中,當(dāng)a或者b關(guān)閉時(shí),case可執(zhí)行了將對(duì)應(yīng)的通道賦值為nil,讓其阻塞這樣就可以等待另一個(gè)通道關(guān)閉。當(dāng)nil通道是select語(yǔ)句的一部分時(shí),它會(huì)被有效地忽略,因此nil通道a會(huì)從select中刪除它,只留下b,直到它被關(guān)閉,退出循環(huán)。

總之,closed和nil通道的簡(jiǎn)單屬性對(duì)寫(xiě)出優(yōu)質(zhì)的go程序是很有用的,可以用來(lái)創(chuàng)建高并發(fā)程序。

Golang net/http 爬蟲(chóng)[1]

上周從零學(xué)習(xí)了golang,語(yǔ)法簡(jiǎn)單關(guān)鍵字少,寫(xiě)個(gè)爬蟲(chóng)熟悉一下語(yǔ)法結(jié)構(gòu)。

首先選用了原生的net/http包,基本上涵蓋了所有的get/post請(qǐng)求,各種參數(shù)都可以設(shè)置,網(wǎng)上google到html頁(yè)面解析goquery神器,很輕松就可以解決頁(yè)面解析問(wèn)題。

首先就寫(xiě)了個(gè)爬取匯率的爬蟲(chóng)。然后重寫(xiě)之前php的一個(gè)請(qǐng)求類(lèi),請(qǐng)求類(lèi)的邏輯有點(diǎn)混亂不清晰,往往把兩個(gè)不同的功能合并到一起寫(xiě),粒度大,后來(lái)發(fā)現(xiàn)了一個(gè)好用的框架——colly,之后再試試好不好用

Windows 10 Golang

依賴(lài)包:goquery

較常用的方法有Find和Each

爬取中國(guó)銀行的匯率牌價(jià)表,golang依賴(lài)net/http包和goquery包

唯一的難點(diǎn)是對(duì)于goquery方法的使用,需要閱讀官方文檔:

使用原生的net/http包基本上可以解決大多數(shù)的網(wǎng)頁(yè)請(qǐng)求,使用goquery可以解決頁(yè)面解析問(wèn)題

可以利用golang的協(xié)程特性進(jìn)行異步多協(xié)程爬取

增加安全性可以通過(guò)幾個(gè)方面進(jìn)行改進(jìn):

1.首先可以限制爬蟲(chóng)的爬取速度

2.每次對(duì)網(wǎng)頁(yè)的請(qǐng)求都隨機(jī)選用一個(gè)客戶(hù)端

3.選用IP代理池,防止IP誤封(及限制ip訪問(wèn)次數(shù))

構(gòu)造請(qǐng)求代理ip網(wǎng)站的鏈接→獲取網(wǎng)頁(yè)內(nèi)容→ 提取網(wǎng)頁(yè)中IP地址和端口號(hào)→驗(yàn)證IP的有效性并存儲(chǔ)

輕量級(jí)反爬蟲(chóng)方案

淺談JSP

golang帶json的Http請(qǐng)求

Get/Post

HTTP請(qǐng)求中的Form Data和Request Payload的區(qū)別

HTTP Json請(qǐng)求

net/http:

golang HTTP操作

python建立爬蟲(chóng)代理ip池

爬蟲(chóng)黑科技之讓你的爬蟲(chóng)程序更像人類(lèi)用戶(hù)的行為

特點(diǎn):事件監(jiān)聽(tīng),通過(guò)callback執(zhí)行事件處理

基于colly開(kāi)發(fā)的web管理界面

2020-08-20:GO語(yǔ)言中的協(xié)程與Python中的協(xié)程的區(qū)別?

福哥答案2020-08-20:

1.golang的協(xié)程是基于gpm機(jī)制,是可以多核多線程的。Python的協(xié)程是eventloop模型(IO多路復(fù)用技術(shù))實(shí)現(xiàn),協(xié)程是嚴(yán)格的 1:N 關(guān)系,也就是一個(gè)線程對(duì)應(yīng)了多個(gè)協(xié)程。雖然可以實(shí)現(xiàn)異步I/O,但是不能有效利用多核(GIL)。

2.golang用go func。python用import asyncio,async/await表達(dá)式。

評(píng)論

go語(yǔ)言的map多協(xié)程訪問(wèn)時(shí)需要加鎖嗎

go語(yǔ)言的map多協(xié)程訪問(wèn)時(shí)需要加鎖

支持==和!=操作就可以做key,實(shí)際上只有function、map、slice三個(gè)kind不支持作為key,因?yàn)橹荒芎蚽il比較不能和另一個(gè)值比較。布爾、整型、浮點(diǎn)、復(fù)數(shù)、字符串、指針、channel等都可以做key。

struct能不能做key要看每一個(gè)字段,如果所有字段都可以做key,那這個(gè)struct就可以。有一個(gè)字段不能做key,這個(gè)struct就不能做key。array也是,元素類(lèi)型能做key,那這個(gè)array就可以。

例如:

type Foo map[struct {

B bool

I int

F float64

C complex128

S string

P *Foo

Ch chan Foo

}]bool

每一個(gè)字段都可以做key,F(xiàn)oo就可以做key。再如:

type Foo map[struct {

Fn func() Foo

M map[*Foo]int

S []Foo

}]bool

有一個(gè)字段不能做key、Foo就不允許做key,而這三個(gè)字段都不能。

字段是遞歸檢查的:

type Foo map[struct {

Sub struct {

M map[*Foo]bool

}

}]bool

Sub的M字段不能做key,Sub就不能做key,F(xiàn)oo也就不能做key。

總之想把一個(gè)數(shù)據(jù)結(jié)構(gòu)用于map的key,就不能包含function、map和slice。

go語(yǔ)言oracle需要獲取多行數(shù)據(jù)信息用什么命令?mysql的為db.Select(),oracle的為什么?

查看表結(jié)構(gòu)的:desc (表名);創(chuàng)建表的create語(yǔ)句就是在plsql上按住Ctrl鍵點(diǎn)擊該表名然后在點(diǎn)擊這個(gè)頁(yè)面右下角的“查看sql“按鈕就可以看到了 ;不使用工具的話(huà),先把表導(dǎo)出來(lái)然后在導(dǎo)進(jìn)去,導(dǎo)進(jìn)去的時(shí)候使用show=y、log這兩個(gè)選項(xiàng),就可以查看了!

文章題目:go語(yǔ)言多協(xié)程讀取數(shù)據(jù) go 協(xié)程 返回值
網(wǎng)頁(yè)網(wǎng)址:http://muchs.cn/article2/docoiic.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供建站公司、品牌網(wǎng)站制作網(wǎng)站制作、響應(yīng)式網(wǎng)站面包屑導(dǎo)航、App開(kāi)發(fā)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶(hù)投稿、用戶(hù)轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話(huà):028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

商城網(wǎng)站建設(shè)