进程:进程是程序在操作系统中的一次执行过程,系统进行资源分配和调度的一个独立单位
线程:线程是进程的一个执行实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位
并发:多线程程序在一个核的cpu上运行,就是并发
并行:多线程程序在多个核的cpu上运行,就是并行
定时器timer(一个定时器只能执行1次)
t1 := time.Now()
timer := time.NewTimer(time.Second)
t2 := <-timer.C (t2就是t1后1s,相当于定时器为1s)
停止定时器:timer.Stop()
重置定时器:timer.Reset()
ticker多次执行的定时器
go语言map并发是不安全的,多个goroutine对一个map操作是会出现错误,因此要使用锁
fatal error: concurrent map writes
map并发时可以使用sync.Map代替map
竞争:有并发,就有资源竞争,如果两个或者多个 goroutine 在没有相互同步的情况下,访问某个共享的资源,比如同时对该资源进行读写时,就会处于相互竞争的状态,这就是并发中的资源竞争。
Mutex 是最简单的一种锁类型,同时也比较暴力,当一个 goroutine 获得了 Mutex 后,其他 goroutine 就只能乖乖等到这个 goroutine 释放该 Mutex
RWMutex 相对友好些,是经典的单写多读模型。在读锁占用的情况下,会阻止写,但不阻止读,也就是**多个 goroutine 可同时获取读锁(同时读) **(调用 RLock() 方法;而写锁(调用 Lock() 方法)会阻止任何其他 goroutine(无论读和写)进来,整个锁相当于由该 goroutine 独占
原子操作 atomic包 atomic包提供了底层的原子级内存操作,对于同步算法的实现很有用,性能优于加锁
Go语言等待组(sync.WaitGroup)
在代码中生硬的使用time.Sleep肯定是不合适的,Go语言中可以使用sync.WaitGroup来实现并发 任务的同步
wg := sync.WaitGroup
每个goroutine开始时wg.Add加1, 结束时wg.Done()减一
wg.wait等待wg!=0时阻塞,等于0时不阻塞
阻塞(程序在返回结果时,程序会被挂起)