Go 并发

Go 并发

  • 并发指的是同时处理多个任务的能力。
  • 并行指的是并行处理多个任务的能力。

并行不必定加快运行速度,由于并行组件之间可能须要互相通讯。并发

Go中使用协程,信道来处理并发。函数

协程

Go中主要经过协程实现并发。线程

协程是与其余函数或方法一块儿并发运行的函数或方法,协程能够看做是轻量级线程,可是建立成本更小,咱们常常会看见数以千计的协程并发运行。code

协程相比线程的优点

  • Go协程建立成本低,堆栈大小只要几K,并能够根据应用须要进行递减,线程必须指定堆栈大小,堆栈是固定不变的。
  • Go中多个协程会复用数量更少的OS线程,就是可能数千个协程公用一个线程。若是线程中一个协程阻塞,OS会再建立一个线程,并把其余的协程复制到新的线程上。
  • Go经过Channel来进行协程间通讯,Channel防止多个协程访问共享内存时发生竞态条件,信道是Go协程间通讯的管道。

建立协程

调用函数或者方法时,在前面加上关键字go能够运行在新协程上。协程

func hello(){
}

func main(){
	go hello()
}

Main函数运行在主协程上,hello并发的运行在新协程上。队列

咱们启动一个新协程,这个新协程会当即返回,而不会等到函数或方法执行完毕。 若是主协程终止,其余协程也会终止。内存

咱们能够在主协程中使用休眠阻塞主协程,等待协程执行完毕。ci

信道(Channel)

信道是协程间通讯的管道。同步

每一个信道都关联一个类型,信道只能运输这种类型的数据,传输其余类型数据是违法的。it

chan T 表示T传输类型的信道

可使用make来定义信道。

a := make(chan int)

经过信道进行发送和接收数据

data : = < - a //读取信道
a <- data // 写入信道

经过信道旁边的箭头指定是发送数据仍是接收数据。

信道的发送和接收默认是阻塞的

当把数据发送到信道时,发送数据语句发生阻塞直到其余Go协程从信道读取到数据才会解除阻塞。

一样,当读取信道数据时,若是没有其余协程把数据写入信道,读取过程会一直阻塞。

Go协程和信道特性没有像其余语言须要加锁和同步的开销。

func hello(done chan bool){
	done < - true // 向信道中写入数据
}

func main(){
	done := make(chan bool)
	go hello(done)
	< - done // 接收数据,会发生阻塞
}

接收多个信道值:

s, c := <-sq, <-cu

死锁

信道使用过程当中须要考虑的重点是死锁,当协程给一个信道发送数据时,按理说其余协程会来接收数据,若是没有的话,会造成死锁。 一样等的从信道读取数据是,也会产生死锁。

单向信道

上面的都是双向信道,即经过信道既能发送数据也能接受数据,咱们也能够建立单向信道,只能发送或者接受数据。

sendch := make(chan<-int) // 建立了只能发送数据的单项信道

当咱们尝试今后信道读取数据时,会报错。

Go中能够把双向信道转换成单向信道这样单向信道能正常读写,可是不能把单向信道转成双向信道。

关闭信道和遍历信道

数据发送方能够关闭信道,通知接收方这个信道再也不产生新数据。

检查信道是否关闭:

v, ok := <- ch // 接收数据,同时用另外一个变量检查关闭状态

若是ok为false,说明通道关闭,获得的值为零值。

func producer(chnl chan int){
	for I := 0; I < 10; I++{
		chill <- I // 循环0~9写入信道
	}
	close(chnl) // 关闭信道 
}

func main(){
	ch := make(chan int)
	go producer(ch)
	for{ // 主函数死循环
		v, ok := <-ch
		if ok == false{ // 检查到信道关闭
			break
		}
	}
}

缓冲信道

上面的都是无缓冲信道,接收和发送数据过程都是阻塞的。

缓冲信道,只有在缓冲满的状况下才会阻塞缓冲信道发送。只有在缓冲为空的时候,才会阻塞信道获取。

经过make函数传递一个容量参数,表明缓冲大小,能够建立缓冲信道。

ch := make(chan type, capacity)

capacity容量应该大于0,无缓冲信道默认容量为0。

一样当缓冲信道堵塞到最大容量时也会产生死锁。

信道长度和容量

容量表明信道能够存储的值数量,使用make函数建立缓冲信道时候会指定容量大小。

缓冲信道长度指的是信道中当前队列元素个数。

相关文章
相关标签/搜索