不同goroutine间进行通讯
a.全局变量和锁同步
package main
import (
"fmt"
"time"
"sync" //运用全局变量需要加锁
)
var {
m = make(map[int]uint64)
lock sync.Mutex() //互斥锁
}
type task struct{
n int
}
func calc(t *task) {
var sum uint64
sum = 1
for i := 1; i < t.n; i++ {
sum *= uint64(i)
}
lock.Lock()
m[t.n] = sum
lock.Unlock()
}
func main(){
for i := 0; i < 16; i++ {
t := &task{n:i}
go calc(t) //使用go并发执行
}
time.Sleep(10 * time.Second)
lock.Lock()
for k, v := range m{
fmt.Println("%d! = %v\n", k, v)
}
lock.Unlock()
}
b.channel,不需要加锁
package main
type student struct{
name string
}
func main(){
var stuChan chan interface{}
stuChan = make(chan interface{}, 10)
stu := student{name: "stu01"}
stuChan <- &stu //写入通道
var stu01 interface{} //通道是接口型,stu01也需要
stu01 = <-stuChan //读通道
fmt.Println(stu01)
var stu02 *student
stu02, ok := stu01.(*student)
if !ok{ //用ok判断报错
fmt.Println("can not convert")
return
}
fmt.Println(stu02)
}
计算素数
package main
import(
"fmt"
"time"
)
func calc(taskChan chan int, resChan chan int, exitChan chan bool) {//计算素数
for v := range taskChan { //遍历任务通道的值
flag := true
for i := 2; i < v; i++ {
if v%i == 0 {
flag == false
}
}
if flag{
resChan <- v //把素数放置结果通道resChan
}
}
fmt.Println("exit")
exitChan <- true
}
func main() {
intChan := make(chan int, 1000)
resultChan := make(chan int, 1000)
exitChan := make(chan bool, 8) //退出resultChan
go func(){ //放入匿名防止lockdown,主线程不阻塞
for i := 0; i < 10000; i++{
intChan <- i
}
close(intChan) //退出for range
}()
for i := 0; i < 8; i++ {//设置8个协程
go calc(intChan, resultChan, exitChan)
}
//等待所有计算的goroutine全部退出
go func(){
for i := 0; i < 8; i++ {
a := <-exitChan
fmt.Println(a)
}
}()
close(resultChan)
for v := range resultChan{
fmt.Println(v)
}
}
检测管道被关闭
package main
import "fmt"
func main(){
var ch chan int
ch = make(chan int, 10)
for i := 0; i < 10; i++ {
ch <- i
}
close(ch) //关闭可读不可写
for {
var b int
b, ok := <-ch //用ok判断
if ok == false{
fmt.Println("chan is close")
break
}
fmt.Println(b)
}
}