Go 語言之旅 2(通道 併發互斥)

2021-09-26 01:54:06 字數 3008 閱讀 4367

這裡要求實現walk和same函式,將樹的值依次送到通道裡,然後在再same裡進行比較。這裡使用到了通道。

package main

import

"golang.org/x/tour/tree"

import

"fmt"

// walk 步進 tree t 將所有的值從 tree 傳送到 channel ch。

func

walk

(t *tree.tree, ch chan

int)

if t.left !=

nil ch <- t.value//節點值送到通道中

if t.right !=

nil}

// same 檢測樹 t1 和 t2 是否含有相同的值。

func

same

(t1, t2 *tree.tree)

bool

}return

true

}func

main()

不同的go 程在訪問同乙個通道的時候,要保證乙個go程一次只能訪問乙個共享的變數,避免衝突。這裡需要利用到互斥(mutual exclusion),go 標準庫里提供了互斥鎖(mutex)這一資料結構來提供這種機制。

package main

import

("fmt"

"sync"

"time"

)// safecounter 的併發使用是安全的。

type safecounter struct

// inc 增加給定 key 的計數器的值。

func

(c *safecounter)

inc(key string

, i int

)// value 返回給定 key 的計數器的當前值。

func

(c *safecounter)

value

(key string

)int

func

main()

for i :=

0; i <

1000

; i++

time.

sleep

(time.second)

//這裡如果不給一點時間讓go程執行一下,map裡的值還沒變就直接輸出了,就會輸出0

fmt.

println

(c.value

("somekey"))

}

package main

import

("fmt"

"time"

"sync"

)type fetcher inte***ce

type urlmap struct

func

(um *urlmap) insert (url string

, body string

)// crawl 使用 fetcher 從某個 url 開始遞迴的爬取頁面,直到達到最大深度。

func

crawl

(um *urlmap, url string

, depth int

, fetcher fetcher)

body, urls, err := fetcher.fetch(url)

if err != nil

fmt.printf("found: %s %q\n", url, body)

for _, u := range urls

return */

// todo: 不重複抓取頁面。

if depth <=

0 body, urls, err := fetcher.

fetch

(url)

if err !=

nil"found: %s %q\n", url, body)

um.insert

(url, body)

for_

, u :=

range urls

return

// 下面並沒有實現上面兩種情況:

/*if depth <= 0

body, urls, err := fetcher.fetch(url)

if err != nil

fmt.printf("found: %s %q\n", url, body)

for _, u := range urls

return

*/}func

main()

gocrawl

(&um,

"",4

, fetcher)

time.

sleep(1

* time.second)

for k,v :=

range um.urlm

}// fakefetcher 是返回若干結果的 fetcher。

type fakefetcher map

[string

]*fakeresult

type fakeresult struct

func

(f fakefetcher)

fetch

(url string)(

string,[

]string

,error

)return"",

nil, fmt.

errorf

("not found: %s"

, url)

}// fetcher 是填充後的 fakefetcher。

var fetcher = fakefetcher,}

,"pkg/"

:&fakeresult,}

,"pkg/fmt/"

:&fakeresult,}

,"pkg/os/"

:&fakeresult,}

,}

go語言通道插入0 Go語言之通道

所以在多個goroutine併發中,我們不僅可以通過原子函式和互斥鎖保證對共享資源的安全訪問,消除競爭的狀態,還可以通過使用通道,在多個goroutine傳送和接受共享的資料,達到資料同步的目的。通道,它有點像在兩個routine之間架設的管道 乙個goroutine可以往這個管道裡塞資料,另外乙個...

go語言之旅 二

package main import fmt func main if else if x 2 0 else num 1 多分支 go語言只有一種迴圈結構,即for迴圈。語法如下 sum 0 for i 0 i 10 i 注意 for語句後面沒有小括號。for語句前後兩部分都是可以省略的,如 su...

go語言之旅 三

指標 go與c語言一樣,擁有指標。指標儲存了值的記憶體位址。型別 t是指向t型別值的指標。其零值為nil。定義如下 var p int 與 c 不同,go 沒有指標運算。結構體 與c語言類似,除了定義方式不同之外,其他都與c相同,如訪問方式 等。陣列 型別 n t 表示擁有 n 個 t 型別的值的陣...