GO协程初识
package mainimport ("fmt""sync""time"
)func read() {defer wg.Done()fmt.Println("read start")time.Sleep(time.Second * 3)fmt.Println("read end")
}func listenMusci() {defer wg.Done()fmt.Println("listenMusci start")time.Sleep(time.Second * 5)fmt.Println("listenMusci end")
}var wg sync.WaitGroup //声明一把锁,同步的一个等待锁,本质是一个计时器,所有的进程都可以共享func main() {start := time.Now().Unix()wg.Add(2)go read() //开启GO并发go listenMusci() //开启GO并发wg.Wait() //计数器为0继续执行//time.Sleep(time.Second * 10) //将main主线程阻塞下end := time.Now().Unix()fmt.Println(end - start)
}
输出结果:
互斥锁
package mainimport ("fmt""sync""time"
)/*互斥锁!!!
互斥锁是一种常用的控制共享资源访问的方法,它能够保证同时只有
一个goroutine可以访问共享资源。Go语言中使用sync包的Mutex类型来实现互斥锁。使用互斥锁能够保证同一时间有且只有一个goroutine进入临界区,
其他的goroutine则在等待锁;当互斥锁释放后,等待的goroutine才可以获取锁进入临界区,
多个goroutine同时等待一个锁时,唤醒的策略是随机的。
*/
var wg sync.WaitGroup //声明一把锁,同步的一个等待锁,本质是一个计时器,所有的进程都可以共享
var lock sync.Mutexvar x = 0func add() {defer wg.Done()//加锁,互斥锁lock.Lock()x++lock.Unlock()println(x)time.Sleep(time.Second * 10) //
}
func main() {wg.Add(100)for i := 0; i < 100; i++ {go add()}wg.Wait() //计数器为0继续执行fmt.Println(x)
}
管道:channel的读写操作
package mainimport ("fmt""reflect"
)/*管道:channel的读写操作!!!chan是go的协程之间通信的数据类型(引用类型)没有索引的概念,取完第一个才能取第二个
*/
func 声明一个管道() {//声明一个管道var ch = make(chan int, 3)//插入值ch <- 12ch <- 13ch <- 15//取值fmt.Println(<-ch)fmt.Println(<-ch)fmt.Println(<-ch)
}//声明一个结构体
type Msg struct {content stringfrom string
}func main() {var ch = make(chan interface{}, 6)ch <- "hello"ch <- truech <- 15ch <- Msg{content: "from kegog", from: "中国北京"}one := <-chfmt.Println(one, reflect.TypeOf(one))fmt.Println(<-ch)fmt.Println(<-ch)//fmt.Println(<-ch)fmt.Println((<-ch).(Msg).content)
}
管道关闭后不能再写入值了
package mainimport "fmt"/*管道的关闭与循环!!
*/
func 管道关闭后不能再写入值了() {ch3 := make(chan int, 10)ch3 <- 1ch3 <- 2ch3 <- 3close(ch3)fmt.Println(<-ch3)ch3 <- 4
}
func main() {管道关闭后不能再写入值了()
}
遍历管道之前要先关闭管道close
package mainimport ("fmt""time"
)func main() {ch := make(chan int, 10)ch <- 1ch <- 2ch <- 3// 方式1go func() {time.Sleep(time.Second * 10)ch <- 4}()for v := range ch {fmt.Println(v, len(ch))// 读取完所有值后,ch的sendq中没有groutineif len(ch) == 0 { // 如果现有数据量为0,跳出循环break}}close(ch)for i := range ch {fmt.Println(i)}}
生产者消费者
package mainimport ("fmt""sync""time"
)func producer(ch chan<- int) {defer wg.Done()for i := 1; i < 11; i++ {time.Sleep(time.Second)ch <- ifmt.Println("生产了:", i)}close(ch)
}func consumer(ch <-chan int) {defer wg.Done()for i := range ch {fmt.Println("消费了:", i)}
}var wg sync.WaitGroupfunc main() {ch := make(chan int, 100)wg.Add(2)go producer(ch)go consumer(ch)wg.Wait()fmt.Println("process end")
}