在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
1.一些概念的介绍:
2.关于并发和并行的理解 解释一:并行是指两个或者多个事件在同一时刻发生;而并发是指两个或多个事件在同一时间间隔发生。 3.并发实例: 每当执行go func,就会创建一个goroutine,在Go语言中,goroutine就是协程。每个goroutine的结构体中有一个sched域就是用于保存自己上下文的。这样,goroutine就可以被换出去,再换进来。这种上下文保存在用户态完成,不必陷入到内核,非常的轻量,切换速度很快。有的协程运行到一定时候就主动调用yield放弃自己的执行,把自己再次放回到任务队列中等待下一次调用时机等。 func trace(start, end int8) { for i:=start; i<=end; i++{ fmt.Printf("%c ", i) time.Sleep(time.Second) } } func main() { runtime.GOMAXPROCS(1) //限制只有一个逻辑处理器 var wg sync.WaitGroup //用于等待所有协程都完成 wg.Add(2) go func(){ defer wg.Done()//程序退出的时候执行 trace('a', 'f') }() go func(){ defer wg.Done()//程序退出的时候执行 trace('A', 'F') }() wg.Wait() //等待所有协程的完成 } 上面的程序使用runtime.GOMAXPROCS(1)来分配一个逻辑处理器供调度器使用,两个goroutine将被该逻辑处理器调度并发执行。输出如下: A a b B C c d D E e f F G g h H I i j J 在go语言中,“有函数调用,就有机会被调度器调度”,在上面案例中trace方法里面调用了time.sleep()函数的目的,就是让当前运行goroutine有机会被调度器调度,进剥夺该goroutine的执行权,让其他的goroutine执行。所以上面代码打印的结果是大小写字母,交替的输出。如果注销掉”time.sleep()”,输出结果为: A B C D E F G H I J a b c d e f g h i j 另一个比较好的例子: package main import ( "fmt" "sync" ) //声明一个全局变量 var waitgroup sync.WaitGroup func Afunction(shownum int) { fmt.Println(shownum) waitgroup.Done() //任务完成,将任务队列中的任务数量-1,其实.Done就是.Add(-1) } func main() { for i := 0; i < 10; i++ { waitgroup.Add(1) //每创建一个goroutine,就把任务队列中任务的数量+1 go Afunction(i) } waitgroup.Wait() //.Wait()这里会发生阻塞,直到队列中所有的任务结束就会解除阻塞 } 4.并发通信 只使用wg.add和wg.Wait显然是不能满足我们的需要的,这时候就需要用到go中的goroutines和通道channel处理并发了。在Go中,所有I/O都被阻塞,通过goroutines和通道channel处理并发,而不是回调和异步。通道channel主要负责在并发过程中,实现通信。通道channel是类型相关的,一个通道channel只能传递一种数据类型的值。 参考:http://www.findme.wang/blog/detail/id/427.html |
请发表评论