• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    公众号

【专栏之读Go语言并发之道】第1,2章 并发概述以及CSP(顺序通信进程) ...

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

本文章收录于我的博客专栏读Go语言并发之道

前言:本文档是读《Go语言并发之道》一书之后的总结,按照章节进行记录。

目录

第一章 并发概述

第二章 对你的代码建模:顺序通信进程(CSP)


第一章 并发概述

  • 1.1 竞争条件

永远不要用time.Sleep来保证你程序运行的逻辑性,这不是一种优雅的方式,更不是一种正确的方式,还可能会给你的程序留下可能潜伏许久的难以调试的bug。

我们应该使用正确的协程间通信的方式来处理资源竞争的状况。

  • 1.2 原子性

当某些东西被定义为原子的,或具有原子性的。那在它的运行过程中,它是不可分割的或不可中断的,即使异常。

原子性的程序在并发环境中是安全的。(通常叫做并发安全/线程安全)

示例说明:我们必须在并发程序以非【原子操作】方式访问共享资源的时候,进行并发同步

data++ 不是原子操作,它可以细分为检索、修改、存储三个操作。

示例中,goroutine和主进程同时访问data,这不是安全的共享资源访问方式。

访问同一块内存的部分也叫做临界区。

  • 1.3 内存访问同步

我们使用一种非常见的方式来解决上个示例的同步问题。

问题:

  1. 以这种方式同步对内存的访问会带来相当大的性能问题,需要改善
  2. 没有解决逻辑正确性,示例中的goroutine和主进程谁先执行?
  3. 临界区应该有多大?
  4. 临界区是否能够频繁进入和退出?

解决这些问题是一种艺术,继续向下看。

 

  • 1.4 死锁、活锁和饥饿

死锁:指的是所有并发进程都在等待其他进程释放锁。这种情况下,若没有外界干预,永远无法恢复。

活锁:活锁指的是任务或者执行者没有被阻塞,由于某些条件没有满足,导致一直重复尝试—失败—尝试—失败的过程。处于活锁的实体是在不断的改变状态,活锁有可能自行解开

例如线程从队列中拿出一个任务来执行,如果任务执行失败,那么将任务重新加入队列,继续执行。假设任务总是执行失败,或者某种依赖的条件总是不满足,那么线程一直在繁忙却没有任何结果。

饥饿:任何情况下,并发进程都无法获得执行工作所需的所有资源。

饥饿更多指的是,有一个或多个贪婪的并发进程,它们争抢较多的共享资源,导致其他并发进程一直得不到资源,一直做无意义的等待。

这多是开发者设计不合理导致的。

 

第二章 对你的代码建模:顺序通信进程(CSP)

 

  • 2.1 并行与并发的区别

a. 大多数时候开发者们讨论的都应该是并发
b. 单核cpu机器上程序运行只有并发,无并行 
c. 单个cpu核心时间片通过快速切换执行不同程序来实现并发 
d. 多线程、协程都是并发模型

  • 2.2 Go语言的并发哲学

CSP是是go语言设计的重要组成部分。

编写并发代码有两种方式可选,一个是CSP,另一种就是内存访问同步;

这其实就是并发模型中的两种通信方式:

     1) 使用sync包就是通过共享内存来通信,这其实会降低并发程序的性能。

     2) sync与其他包中可以让你执行锁,创建资源池取代goroutine。

 

sync包文档中有如下描述:

在Go语言的FAQ中有:

如何选择选择合适的并发通信模型?

书中原话:使用最好描述,和最简单的那个方式。

书中推荐的决策方式:

Go语言的并发哲学总结:追求简洁,尽量使用channel,并且认为goroutine的使用是(几乎)没有成本的。(译文没有"几乎"二字,但个人认为添上更合理)

 

 


鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
go实现发布时间:2022-07-10
下一篇:
[Go] golang http下返回json数据发布时间:2022-07-10
热门推荐
热门话题
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap