并发和并行的区别thedifferencebetweenconcurrencyandparallel并发:你的程序看起来像是在同时运行,但从微观的角度看,threads在来回切换。 只能在一个核心processer上运行。
图像: (来自堆栈覆盖) )。
---------------------------并行:你的程序真的可以在一台机器上同时运行
图像: (来自堆栈覆盖) )。
------------------- -并行实现的两种方法shared----memory当多个内核共享一个内存进行读写时,race condition等
消息传递每个内核都有自己的内存空间,通过消息传递共享内存并进行交互。
例如,了解共享内存和消息传递(go )1-1.共享内存权重矩阵
packagemainimport(fmt ) sync ) ) varretintvarwgsync.wait group//varmtxsync.mutexfuncsum ) nums[]int )/MTX ilen (ntx I { ret=nums [ I ] }/MTX.unlock (WG.done ) }func main ) ) WG.add )2) nums:=make ) []int,100000 i 100000; I { nums [ I ]=i1 } gosum (nums [ :50000 ] ) gosum(nums[50000336010000] ) WG.wait (fmt.println ) ) (gosum ) i 100000; I{s=I1}fmt.println('sum=',s )的三次结果不正确,这是因为同时写入内存导致的race condition问题。
可能的情况是:
在sum=1go1写入之前,go2读取sum=1go1并写入sum=1,此时sum=1=2go2写入sum =2,此时sum=1=2=3在go1写入操作被复盖而发生错误的情况下
1-2. share-memory with mutex
packagemainimport(fmt ) sync ) (varretintvarwgsync.waitgroupvarmtxsync.mutexfuncsum ) nums[]int ) { mtx.Lock ) ) Ilen(nums ); I { ret=nums [ I ] } MTX.unlock (WG.done ) }func main ) ) WG.add )2) nums:=make ) []int,100000 ) fok i 100000 I { nums [ I ]=i1 } gosum (nums [ :50000 ] ) gosum(nums[50000336010000] ) WG.wait (fmt.println ) ) (gosum ) i 100000; I{s=I1}fmt.println('sum=',s ) } 2. message-passing
packagemainimport(fmt(sync ) ) varwgsync.wait group//varmtxsync.mutexfuncsum ) nums[]int,c chan int ) ) varsunc I { sum=nums [ I ] }/MTX.unlock (c-sum WG.done ) }func main ) ({C1:=make ) chanint,1 ) c 23360=make I 10000000000 I { nums [ I ]=i1 } gosum (nums [ :50000 ],c1 ) gosum ) nums[50000336010000],c2 ) wg.Wait ) sum 13360=-sum 13360 I{s=I1}fmt.println(sum:=',s ) }消息传递每个goroutine都有独立的内存空间,因此不需要mutex。
每个goroutine (更轻量级的线程thread )完成后,将sum传递给channel以实现消息传递。
Summary同时和并行的不同同时在微观的视点上并不是同时执行,只是thread来来往往。 并行在真正意义上同时执行,并在至少两个核心processer中执行。 同时实现的两种方式shared-memory:容易实现,但容易发生race condition。 消息传递: go语言推荐实践。