一、设置程序运行的CPU数量
package main
import (
"fmt"
"runtime"
)
func main() {
//获取当前系统CPU的数量
num:=runtime.NumCPU()
//设置num-1的cpu运行程序
//runtime.GOMAXPROCS(num-1)
fmt.Println(num)
}
二、使用互斥锁解决资源竞争的问题
package main
import (
"fmt"
"sync"
"time"
)
var(
mp =make(map[int]int,10)
lock sync.Mutex
)
func test(n int){
lock.Lock()
mp[n]=n
lock.Unlock()
}
func main() {
for i:=0;i<200;i++{
go test(i)
}
time.Sleep(time.Second*10)
for i:=0;i<200;i++{
fmt.Println(mp[i])
}
}
三、使用管道channel解决资源竞争的问题
package main
import ( "fmt"
)
func main() {
//演示一下管道的使用
//1. 创建一个可以存放 3 个 int 类型的管道
var intChan chan int
intChan = make(chan int, 3)
//2. 看看 intChan 是什么
fmt.Printf("intChan 的值=%v intChan 本身的地址=%p
", intChan, &intChan)
//3. 向管道写入数据
intChan<- 10
num := 211
intChan<- num
intChan<- 50
// intChan<- 98//注意点, 当我们给管写入数据时,不能超过其容量
//4. 看看管道的长度和 cap(容量)
fmt.Printf("channel len= %v cap=%v
", len(intChan), cap(intChan)) // 3,
//5. 从管道中读取数据
var num2 int
num2 = <-intChan
fmt.Println("num2=", num2)
fmt.Printf("channel len= %v cap=%v
", len(intChan), cap(intChan)) // 2, 3
//6. 在没有使用协程的情况下,如果我们的管道数据已经全部取出,再取就会报告 deadlock
//num3 := <-intChan
//num4 := <-intChan
//num5 := <-intChan
//fmt.Println("num3=", num3, "num4=", num4, "num5=", num5)
}
四、遍历管道
package main
import "fmt"
func main() {
var arr chan int
arr=make(chan int,100)
for i:=1;i<101;i++{
arr<-i*5
}
close(arr)//遍历管道必须关闭,否则会报错deadlock
for v:=range arr{
fmt.Println(v)
}
}
五、channel使用注意事项和细节
1) channel 可以声明为只读,或者只写性质

2)使用 select 可以解决从管道取数据的阻塞问题
package main
import ( "fmt"
"time"
)
func main() {
//使用 select 可以解决从管道取数据的阻塞问题
//1.定义一个管道 10 个数据 int
intChan := make(chan int, 10)
for i := 0; i < 10; i++ {
intChan <- i
}
//2.定义一个管道 5 个数据 string
stringChan := make(chan string, 5)
for i := 0; i < 5; i++ {
stringChan <- "hello" + fmt.Sprintf("%d", i)
}
//传统的方法在遍历管道时,如果不关闭会阻塞而导致 deadlock
//问题,在实际开发中,可能我们不好确定什么关闭该管道. //可以使用 select 方式可以解决
//label:
for {
select {
//注意: 这里,如果 intChan 一直没有关闭,不会一直阻塞而 deadlock
//,会自动到下一个 case 匹配
case v := <-intChan:
fmt.Printf("从 intChan 读取的数据%d
", v)
time.Sleep(time.Second)
case v := <-stringChan:
fmt.Printf("从 stringChan 读取的数据%s
", v)
time.Sleep(time.Second)
default:
fmt.Printf("都取不到了,不玩了, 程序员可以加入逻辑
")
time.Sleep(time.Second)
return
//break label
}
}
}