Basic introduction and quick start of Golang channelle (pipeline)

channel (pipeline)-basic introduction


Why do we need channels? Previously, global variables were used to lock and synchronize to solve goroutine communication, but it was not perfect.

1) It is difficult to determine the time the main thread waits for all goroutines to complete. We set 10 seconds here, which is just an estimate.
2) If the main thread sleeps for a long time, the waiting time will be lengthened. If the waiting time is short, there may still be goroutine in the working state. At this time, It will be destroyed when the main thread exits
3) Communication is achieved through global variable lock synchronization, and does not use multiple coroutines to read and write global variables.
4) All the above analyzes are calling for a new communication mechanism channel

package main

import (
	"fmt"
	"sync"
	"time"
)

var (
	m = make(map[int]int, 10)
	//声明一个全局的互斥锁  lock是一个全局的互斥锁
	//sync是包 同步的意思 mutex是互斥的意思
	lock sync.Mutex
)

// test函数就是计算n的阶乘
func test(n int) {
	res := 1
	for i := 1; i <= n; i++ {
		res = res * i
	}
	//将计算结果放到map当中 加锁
	lock.Lock()
	m[n] = res
	lock.Unlock()
}

func main() {
	//这里开启多协程完成任务
	for i := 1; i <= 20; i++ {
		go test(i)
	}

	time.Sleep(time.Second * 10)
	for k, v := range m {
		fmt.Println(k, v)
	}
}


 

Introduction to channel


1)Channle is essentially a data structure - a queue, the data is first in first out
2) Thread safety,When accessed by multiple goroutines, no It needs to be locked, which means that the channel itself is thread-safe (pipes are thread-safe. When you read the pipe, no matter how many coroutines are operating on the same pipe, you can use it with confidence and no errors will occur. These It is maintained by the compiler at the bottom level)
3) Channels have types. A string channel can only store string type data. (If you want to put int or float in the pipe, you can use the empty interface interface type)
 

Define/declare channel


var variable name chan data type

Example:

var intChan chan int (intChan用于存放int数据)
var mapChan chan map[int]string  (mapChan用于存放map[int]string类型)
var perChan chan Person
var perChan2 chan *Person

illustrate:

1)channel is quotation type

2)The channel must be initialized before data can be written, that is, it can be used after make

3) Pipes are typed, intChan can only write integer int

channel initialization


Description: Use make to initialize

var intChan chan int
intChan =make(chan int,10)

Write (store) data to the channel

var intChan chan int
intChan =make(chan int,10)
num =999
intChan<-10
intChan<-num

If the channel is passed to another function, the same pipe is operated in this function because it is a reference type.

package main

import "fmt"

func main() {
	var intChan chan int
	//创建可以存放3个int类型的管道
	intChan = make(chan int, 3)

	//看看intChan是什么
	fmt.Printf("initChan的值为=%v\n initChan本身地址为%p\n", intChan, &intChan)

	//向管道写入数据
	intChan <- 1
	num := 2
	intChan <- num
	//当给管道写入数据的时候,不能超过其容量
	//看看管道的长度和cap
	fmt.Println("长度:", len(intChan), "容量:", cap(intChan))

	num1 := <-intChan
	fmt.Println("取出来的第一个数据是:", num1)
	fmt.Println("取出之后的长度:", len(intChan), "取出之后的容量:", cap(intChan))

	//在没有使用协程的情况下,如果我们的管道数据已经全部取出,再取就会报告deadlock
}


initChan的值为=0xc00007a080
initChan本身地址为0xc00000a028
长度: 2 容量: 3                    
取出来的第一个数据是: 1            
取出之后的长度: 1 取出之后的容量: 3

What kind of data should be put into the pipeline? This kind of data is flowing. It is put in on one side and read on the other side. In this way, a communication mechanism is formed. <-ch This acceptance method can also be used to throw away the data. The data is not wanted. This is also a way to obtain it, but it is not wanted.

 Notes on channel usage


1.Only specified data types can be stored in the channel

2. Once the channel data is full, no more data can be added (a deadlock error will occur)

3. After taking out data from the channel, you can continue to put it in

4. Without the use of coroutines, if the channel data is fetched and then fetched again, a dead lock will be reported.

Read and write channel case 


Many maps can be stored in the pipeline, and each map can have multiple key/value pairs. Here you need to make it before using map.

Pipes can also store structure instances.

Pointers can also be stored in pipes.

If we want to store mixed-type data in this pipe, we want to put both structures and strings. The data type here is the empty interface type interface{}, because any data type is considered to implement the empty interface.

Note: Remember to use type assertion when taking it out.

package main

import (
	"fmt"
	"reflect"
)

type Cat struct {
	Name string
	Age  int
}

func main() {
	allChan := make(chan interface{}, 3)
	cat1 := Cat{
		Name: "1",
		Age:  10,
	}

	allChan <- "hello"
	allChan <- 1
	allChan <- cat1

	<-allChan
	<-allChan
	newCat := <-allChan
	fmt.Println(reflect.TypeOf(newCat))
	fmt.Printf("%T\n %#v\n", newCat, newCat)
	//fmt.Println(c.Name, c.Age) 这种写法是错误的,编译器通不过,使用类型断言即可
	c := newCat.(Cat)
	fmt.Println(c.Name, c.Age)
}

6) Store functions

ch := make(chan func(string) string, 10)
ch <- func(name string) string {  //使用匿名函数
	return "hello " + name
}

Guess you like

Origin blog.csdn.net/qq_34556414/article/details/134826552