
golang并发编程
月守护
卡拉卡拉
展开
-
信号量的使用方法
简介信号量是并发编程中常见的一种同步机制,在需要控制访问资源的线程数量时就会用到信号量使用场景在需要控制访问资源的线程数量时就会需要信号量我来举个例子帮助你理解。假设我们有一组要抓取的页面,资源有限最多允许我们同时执行三个抓取任务,当同时有三个抓取任务在执行时,在执行完一个抓取任务后才能执行下一个排队等待的任务。当然这个问题用Channel也能解决,不过这次我们使用Go提供的信号量原语来解决这个问题,代码如下:package mainimport ( "context" "fm原创 2021-01-25 09:26:30 · 1180 阅读 · 0 评论 -
atomic原子操作
atomic原子操作在一些场景下,相比于其他的并发原语,性能更优举个例子:假设你想在程序中使用一个标志(flag,比如一个 bool 类型的变量),来标识一个定时任务是否已经启动执行了,你会怎么做呢?我们先来看看加锁的方法。如果使用 Mutex 和 RWMutex,在读取和设置这个标志的时候加锁,是可以做到互斥的、保证同一时刻只有一个定时任务在执行的,所以使用 Mutex 或者 RWMutex 是一种解决方案。其实,这个场景中的问题不涉及到对资源复杂的竞争逻辑,只是会并发地读写这个标志,这类场景就适合使用原创 2021-01-04 14:54:27 · 268 阅读 · 0 评论 -
golang控制并发(sync.WaitGroup和context.Context)
我们都知道,在golang中很容易实现并发,只需要一个关键字go就可以。但是在开启了多个goruntine之后,我们要如何去管理它们呢(包括停止退出goroutine,等待goruntine执行完成,继续让goruntine执行等)。这些我们在日常的业务中都可能碰到,下面就讲讲在不同的场景如何正确优雅地管理goruntine,即控制并发。一,sync.WaitGroup...原创 2020-11-13 11:13:32 · 1704 阅读 · 0 评论 -
golang的检测并发访问共享资源是否有问题的工具--race detetor
Go race detector 是基于 Google 的 C/C++ sanitizers 技术实现的,编译器通过探测所有的内存访问,加入代码能监视对这些内存地址的访问(读还是写)。在代码运行的时候,race detector 就能监控到对共享变量的非同步访问,出现 race 的时候,就会打印出警告信息。这个技术在 Google 内部帮了大忙,探测出了 Chromium 等代码的大量并发问题。Go 1.1 中就引入了这种技术,并且一下子就发现了标准库中的 42 个并发问题。现在,race detector原创 2020-12-09 17:45:08 · 816 阅读 · 0 评论 -
golang中的互斥锁
mutex是golang提供的基础并发原语,可以帮助我们处理多goruntine并发访问共享资源的问题。每个goruntine都要再获取到锁之后才能操作共享资源,完成操作释放锁,保证了共享资源的读写安全性。但这种方式也可能带来一些问题:一些悲惨的goruntine一直获取不到锁,导致业务逻辑不能继续完整执行,这种问题被称为"饥饿问题"为了解决这种问题,mutex在长时间的发展中不断完善,目前有两种操作模式,防止饥饿问题的出现饥饿模式和正常模式正常模式当前的mutex只有一个goruntine来获原创 2020-12-09 18:34:46 · 620 阅读 · 0 评论 -
Cond--条件变量并发原语
先不讲这个cond是什么,我们从一个场景出发:有一个慈善机构需要募集善款,目标比方说是100万。那就需要发一个公告,说需要筹集善款100万。群众看到公告就开始捐钱,每个人能力不一样,有的可能1万,有的可能2万,有的人看着不够再捐一笔。为了更快的筹够善款,那肯定是人越多越好,那在计算机世界就是用上所有的cpu资源。很快100万就够了,慈善机构就再发一个公告,说钱够了,大家不用捐了。那这个消息传递可能有延迟,收到的钱比100万多那也没办法,收多少算多少呗,只要能如实公示,正确使用就行了把上诉场景抽象一下,这原创 2020-12-11 17:37:34 · 414 阅读 · 0 评论 -
Once:一个简约而不简单的并发原语
Once 可以用来执行且仅仅执行一次动作,常常用于单例对象的初始化场景。Once 的使用场景sync.Once 只暴露了一个方法 Do,你可以多次调用 Do 方法,但是只有第一次调用 Do 方法时 f 参数才会执行,这里的 f 是一个无参数无返回值的函数func main() { var once sync.Once // 第一个初始化函数 f1 := func() { fmt.Println("in f1") } once.Do(f1) //原创 2020-12-14 11:09:05 · 203 阅读 · 0 评论