go 多執行緒

2021-08-27 04:02:13 字數 3053 閱讀 6719

個人分類: go

goroutine 

runtime包中提供了幾個與goroutine相關的函式。gosched()讓當前正在執行的goroutine放棄cpu執行許可權。排程器安排其他正在等待的執行緒執行。 

請看以下例子:

package main

import (

"runtime"

"fmt"

)func main()

func sayhello()

}func sayworld()

}

這種情況是單核的時候,如果是多核的話runtime.gomaxprocs(1),變成單核,多核的話,每次都不一樣,因為放棄cpu執行的許可權,另乙個cpu還是會繼續的。

從上面輸出結果可知,我們啟動了兩個執行緒,其中乙個執行緒輸出一句後呼叫gosched函式,釋放cpu許可權;之後另乙個執行緒獲得cpu許可權。這樣兩個執行緒交替獲得cpu許可權,才輸出了以上結果。

runtime.numcpu()返回了cpu核數,runtime.numgoroutine()返回當前程序的goroutine執行緒數。即便我們沒有開啟新的goroutine。

runtime.goexit()函式用於終止當前的goroutine,單defer函式將會繼續被呼叫。

package main

import (

"runtime"

"fmt"

)func test()()

for i := 0; i < 10; i++

}}func main()

var str string 

fmt.scan(&str) 

這兩句**是等待輸入的意思,在這裡用來阻止主線程關閉的。如果沒有這兩句的話,會發現我們的程式瞬間就結束了,而且什麼都沒有輸出。這是因為主線程關閉之後,所有開啟的goroutine都會強制關閉,他還沒有來得及輸出,就結束了。 

但是這樣感覺怪怪的。如果有一種機制,在子執行緒結束的時候通知一下主線程,然後主線程再關閉,豈不是更好,這樣就不用無休止的等待了。於是就有了channel。

channel 

goroutine之間通過channel來通訊,可以認為channel是乙個管道或者先進先出的佇列。你可以從乙個goroutine中向channel傳送資料,在另乙個goroutine中取出這個值。 

使用make建立

var channel chan int = make(chan int)

// 或

channel := make(chan int)

生產者/消費者是最經典的使用示例。生產者goroutine負責將資料放入channel,消費者goroutine從channel中取出資料進行處理。

package main

import (

"fmt"

)func main()

func producer(c chan int)

}func consumer(c, f chan int)else}f

}

執行結果 

可以將channel指定為單向通訊。比如

func producer(c chan

}func consumer(c }f

}channle可以是帶緩衝的。make的第二個引數作為緩衝長度來初始化乙個帶緩衝的channel:

c := make(chan int, 5) 

向帶緩衝的channel傳送資料時,只有緩衝區滿時,傳送操作才會被阻塞。當緩衝區空時,接收才會阻塞。 

可以通過以下程式調整傳送和接收的順序除錯

package main

import (

"fmt"

)func main()

select 

如果有多個channel需要監聽,可以考慮用select,隨機處理乙個可用的channel

package main

import (

"fmt"

)func main()

quit

}()testmuti(c, quit)

}func testmuti(c, quit chan int)}}

channle超時機制 

當乙個channel被read/write阻塞時,會被一直阻塞下去,直到channel關閉。產生乙個異常退出程式。channel內部沒有超時的定時器。但我們可以用select來實現channel的超時機制

package main

import (

"time"

"fmt"

)func main()

}

執行緒同步 

假設現在我們有兩個執行緒,乙個執行緒寫檔案,乙個執行緒讀檔案。如果在讀檔案的同時,寫檔案的執行緒向檔案中寫資料,就會出現問題。為了保證能夠正確的讀寫檔案,在讀檔案的時候,不能進行寫入檔案的操作,在寫入時,不能進行讀的操作。這就需要互斥鎖。互斥鎖是執行緒間同步的一種機制,用了保證在同一時刻只用乙個執行緒訪問共享資源。go中的互斥鎖在sync包中。下面是個執行緒安全的map:

package main

import (

"errors"

"sync"

"fmt"

)func main()

go setvalue(m)

go m.display()

var str string

fmt.scan(&str)

}type mymap struct

func (this *mymap)get(key string)(int, error)

return i, nil

}func (this *mymap)set(key string, val int)

func (this *mymap)display()

}func setvalue(m *mymap)

}

執行結果 

go之多執行緒

在go裡面,併發程式依靠的是goroutine和channel。goroutine可以理解為執行緒,當對乙個函式呼叫go,啟動乙個goroutine的時候,就相當於起來乙個執行緒來執行這個函式。比如 func getinfo name string,age int func main 輸出 star...

go語言多執行緒操作map

go語言裡的map因為是引用,所以多執行緒操作時必須加鎖.一開始我以為只要讀寫的key不會競爭就不會出現問題,但是測試後發現,即使寫的時候採用的是不同的key,也會發生多執行緒錯誤 fatal error concurrent map writes func main go func time.sl...

多執行緒 多執行緒原理

我們首先要知道什麼是多執行緒,說白了就是多個執行緒,執行緒是什麼呢,其實就是程序執行的途徑,那麼說道這裡我們又引入了乙個新的名字,就是程序,那麼我們來看看什麼是程序,其實我們自己也能看到,啟動電腦的任務管理器,我們就可以看到程序選項,裡面是我們電腦所有的程序,我們會發現有很多的程序.簡單地說就是程序...