go語言關於線程與通道channal


在go語言中,封裝了多線程的使用方法,使其變得簡單易用。

在這里說說自己一點體會,不正確的地方還是請各位大牛指正。

關於go語言的並發機制,這很簡單,在你要執行的函數前面加上go即可

比如:

package main

import(
"fmt" ) func main(){ go fmt.Println("1") fmt.Println("2") }

好了 這樣即可使用,但是這個程序運行的時候會出問題,你會發現1打印不出來,為啥?

你問我為啥?

這是因為在執行這個的時候,你可以想像,程序優先執行主線程,這時會打印出2,然后程序就退出了,這個時候程序還沒來及打印並發下的1,就退出了所以你看不到!!

那么怎么才能看到哪?

加個延時,等到線程把事情搞完才退出就能看到了,就像這樣

package main

import(

         "fmt"

)
func main(){

    go fmt.Println("1")

    fmt.Println("2")    

   time.Sleep(time.Second*1) }

這樣你就會發現,其實程序先打印2,在打印1,因為是主線程優先的,所以會出現這種狀況(我猜的,管你信不信,好吧這是真的,你問誰都是這樣給你說)

不管怎么說,我就問你這個多線程學起來簡單不簡單?你覺得是CreateThread()爽,還是這個爽!

 

下面說說通道channal

這個哪,你就可以理解成多線程之間通信的一個通道。

你問我怎么用這東西?

ch:=make (chan int)

chan是通道的關鍵字

make那就是創建的意思

int 那就是int類型的通道

簡單不簡單,開心不開心?

你開心的太早了,哈哈哈哈哈

上面僅僅是說了基本的用法,這里還有點東西需要在詳細的說下,不然你還是不懂怎么用chan搞事情!

上面的

ch := make(chan int)

是創建一個無緩沖區的int類型的chan,具體什么叫無緩沖區,額,不知道怎么解釋,以后再說吧

ch :=make(<-chan int)

這個是無緩沖區只讀的ch

ch:=make(chan<- int)

無緩沖只寫的 chan

關於"<-"符號,在go的多線程中會經常碰到,你需要知道一點這個是做什么用的

按照我的理解:

ch<-

這個意思是將數據寫入ch

<-ch這個意思是將數據從ch中讀出來

還是一個小例子說下相關的東西:

package main
import(

    "fmt"

//    "time"
)
func main(){

    ch:=make(chan int)
    ch<-1
    go func (){
        <-ch
        fmt.Println("1")
    }()
    fmt.Println(":2")


}

運行之后會告訴你,死鎖了,為什么會出現?他是無緩沖區,也就是賦值必須要進去取值。不然就是死鎖

package main
import(

	"fmt"

//	"time"
	"time"
)
func main(){

	ch:=make(chan int,1)
	ch<-1


	go func (){
		v:=<-ch
		fmt.Println(v)
	}()
	fmt.Println(":2")
	time.Sleep(time.Second*1)

}

 這樣試試看哪

package main
import(

"fmt"

// "time"
"time"
)
func main(){

ch:=make(chan int)



go func (){
v:=<-ch
fmt.Println(v)
}()
ch<-1
fmt.Println(":2")


}

或者這樣,后面這個是無緩沖區的,這樣的話,ch在賦值的時候被阻塞,知道gofunc給取走,這樣打印出來的結果就是1,2

生產消費者:

import (

    "fmt"
    "time"
)
func produce(p chan<- int) {
    for i := 0; i < 10; i++ {
        p <- i
        fmt.Println("send:", i)
    }
}
func consumer(c <-chan int) {
    for i := 0; i < 10; i++ {
        v := <-c
        fmt.Println("receive:", v)
    }
}
func main() {
    ch := make(chan int)
    go produce(ch)
    go consumer(ch)
    time.Sleep(1 * time.Second)
}

這個例子,我覺得能夠體現的更明顯,無緩沖區意味着這就是同步的,也就是說只能是ch寫入,取出,寫入,取出,寫入,取出這樣走,無緩沖區必須保證一個寫入,另一個取出,才能執行下一次

 

再看看這個:

import (

    "fmt"
    "time"
)
func produce(p chan<- int) {
    for i := 0; i < 10; i++ {
        p <- i
        fmt.Println("send:", i)
    }
}
func consumer(c <-chan int) {
    for i := 0; i < 10; i++ {
        v := <-c
        fmt.Println("receive:", v)
    }
}
func main() {
    ch := make(chan int, 10)
    go produce(ch)
    go consumer(ch)
    time.Sleep(1 * time.Second)
}


 

再來看看這個,這個有緩沖區的,啥意思?

就是我有個容器,我可以一直往里面生產,知道這個被填滿,也就是我可以一直往這個緩沖區塞東西,直到這10個被填滿,我也可以一直讀數據,也可以一下全部取出來。

大概就是這么意思。

 

參考文檔:

http://studygolang.com/articles/3311


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM