在学习<The Go Programming Language>第八章并发单元的时候还是遭遇了不少问题,和值得总结思考和记录的地方. 做一个类似于unix du命令的工具.但是阉割了一些功能,这里应该只实现-c(统计total大小) 和-h(以human比较容易辨识的显示出来)的功能. 首先我们需要构造一个 能够返回FileInfo信息数组的函数,我们把它取名为dirEntries: func dirEntries(dir string) []os.FileInfo { entries, er…
Channel 1. 概述 “网络,并发”是Go语言的两大feature.Go语言号称“互联网的C语言”,与使用传统的C语言相比,写一个Server所使用的代码更少,也更简单.写一个Server除了网络,另外就是并发,相对python等其它语言,Go对并发支持使得它有更好的性能. Goroutine和channel是Go在“并发”方面两个核心feature. Channel是goroutine之间进行通信的一种方式,它与Unix中的管道类似. Channel声明: ChannelType = (…
golang的Channel Channel 是 golang 一个非常重要的概念,如果你是刚开始使用 golang 的开发者,你可能还没有真正接触这一概念,本篇我们将分析 golang 的Channel 1. 引入 要讲 Channel 就避不开 Goroutine -- 协程.闲话不说, 直接上个例子 Goroutine demo: package main import ( "fmt" "time" ) func main() { origin := 1 go…
一.线程并发同步概念 线程同步其核心就在于一个“同”.所谓“同”就是协同.协助.配合,“同步”就是协同步调昨,也就是按照预定的先后顺序进行运行,即“你先,我等, 你做完,我再做”. 线程同步,就是当线程发出一个功能调用时,在没有得到结果之前,该调用就不会返回,其他线程也不能调用该方法. 就一般而言,我们在说同步.异步的时候,特指那些需要其他组件来配合或者需要一定时间来完成的任务.在多线程编程里面,一些较为敏感的数据时不允许被多个线程同时访问的,使用线程同步技术,确保数据在任何时刻最多只有一个线程…
ManualResetEvent,即手动重置事件,通过信号量来判别当前线程是否应该阻塞或继续执行.使用方式与ManualResetEventSlim差不多,ManualResetEventSlim只是针对ManualResetEvent轻量化的使用. 一.在控制台应用程序中测试 请看如下代码: private static ManualResetEvent mre = new ManualResetEvent(true); static void Main(string[] args) { //…
由于项目有某种需求,在WebApi中,有大量的请求需要操作相同的数据,因此需要用到并发同步机制去操作共享的数据. 本次配合使用Interlocked和ManualResetEventSlim来实现并发同步的目的. Interlocked实现了原子性的操作,ManualResetEventSlim提供信号量等待唤醒机制. 以上两个关键字,自行找度娘了解. 代码如下: [HttpGet("[controller]/v1/api/[action]")] public IActionResul…
Mutex,中文译为互斥体,在.net中也是作为一种线程或进程之间的互斥体存在.即在同一时刻,一个共享资源只允许被某一个线程或进程访问,其他线程或进程需要等待(直至获取互斥锁为止). Mutex的使用方式与Monitor很相似,但绝不相同.Monitor支持线程间并发同步,Mutex不但支持线程也支持进程间并发同步. Mutex有许多需要注意的地方,如果稍不注意,则你会被坑惨! 接下来我们使用控制台和webapi项目各自做测试. 一.使用控制台测试进程间的同步 测试代码如下: [STAThrea…
在.net中,还可以使用Monitor实现线程并发同步.Monitor类是纯托管且完全可移植,并且可能会在操作系统资源需求方面更加高效. Monitor的锁对象尽可能使用引用对象,如果是字符串或值对象,会出现引发SynchronizationLockException异常. 其实我们日常用的lock锁同步,其原理就是基于Monitor的. 即: public static readonly object locker=new object(); lock(locker){ //to do som…
innodb是一个多线程并发的存储引擎,内部的读写都是用多线程来实现的,所以innodb内部实现了一个比較高效的并发同步机制. innodb并没有直接使用系统提供的锁(latch)同步结构,而是对其进行自己的封装和实现优化.可是也兼容系统的锁.我们先看一段innodb内部的凝视(MySQL-3.23): Semaphore operations in operating systems are slow: Solaris on a 1993 Sparc takes 3 microseconds…
使用.NET的 BlockingCollection<T>来包装一个ConcurrentQueue<T>来实现golang的channel. 代码如下: public class Channel<T> { private BlockingCollection<T> _buffer; ) { } public Channel(int size) { _buffer = new BlockingCollection<T>(new Concurrent…
golang的channel实现位于src/runtime/chan.go文件.golang中的channel对应的结构是: // Invariants: // At least one of c.sendq and c.recvq is empty, // except for the case of an unbuffered channel with a single goroutine // blocked on it for both sending and receiving usi…
作者:汤圆 个人博客:javalover.cc 前言 官人们好啊,我是汤圆,今天给大家带来的是<Java并发-同步容器篇>,希望有所帮助,谢谢 文章如果有问题,欢迎大家批评指正,在此谢过啦 简介 同步容器主要分两类,一种是Vector这样的普通类,一种是通过Collections的工厂方法创建的内部类 虽然很多人都对同步容器的性能低有偏见,但它也不是一无是处,在这里我们插播一条阿里巴巴的开发手册规范: 高并发时,同步调用应该去考量锁的性能损耗.能用无锁数据结构,就不要用锁:能锁区块,就不要锁整…
目录 1.什么是 channel,介绍管道 2.channel 的基本使用 3.channel 的使用场景 4.使用 channel的注意事项及死锁分析 什么是 channel 管道 它是一个数据管道,可以往里面写数据,从里面读数据. channel 是 goroutine 之间数据通信桥梁,而且是线程安全的. channel 遵循先进先出原则. 写入,读出数据都会加锁. channel 可以分为 3 种类型: 只读 channel,单向 channel 只写 channel,单向 channe…
参考资料: https://groups.google.com/forum/#!topic/golang-china/q4pFH-AGnfs…
Golang作为一个略古怪而新的语言,有自己一套特色和哲学.从其他语言转来的开发者在刚接触到的时候往往大吃苦头,我也不例外.这篇文章很细致地介绍了Golang的一些常见坑点,读完全篇中枪好多次.故将其转载.由于文章很长,分为上下两部分,第一部分记录初级篇,第二部分记录进阶和高级篇:此为第二部分,若要看第一部分,请转至这里 感谢原文作者Kyle Quest以及翻译者影风LEY.出处见下: 原文链接:http://devs.cloudimmunity.com/gotchas-and-common-m…
初级篇 开大括号不能放在单独的一行 未使用的变量 未使用的Imports 简式的变量声明仅可以在函数内部使用 使用简式声明重复声明变量 偶然的变量隐藏Accidental Variable Shadowing 不使用显式类型,无法使用“nil”来初始化变量 使用“nil” Slices and Maps Map的容量 字符串不会为“nil” Array函数的参数 在Slice和Array使用“range”语句时的出现的不希望得到的值 Slices和Arrays是一维的 访问不存在的Map Key…
笔者在<Golang 入门 : 竞争条件>一文中介绍了 Golang 并发编程中需要面对的竞争条件.本文我们就介绍如何使用 Golang 提供的 channel(通道) 消除竞争条件. Channel 是 Golang 在语言级别提供的 goroutine 之间的通信方式,可以使用 channel 在两个或多个 goroutine 之间传递消息.Channel 是进程内的通信方式,因此通过 channel 传递对象的过程和调用函数时的参数传递行为比较一致,比如也可以传递指针等.使用通道发送和接…
代码示例: package main import ( "fmt" "time" "golang.org/x/net/context" ) func main() { // ctx, cancelFunc := context.WithDeadline(context.Background(), time.Now().Add(time.Second*5)) ctx, cancelFunc := context.WithTimeout(contex…
Catena (时序存储引擎)中有一个函数的实现备受争议,它从 map 中根据指定的 name 获取一个 metricSource.每一次插入操作都会至少调用一次这个函数,现实场景中该函数调用更是频繁,并且是跨多个协程的,因此我们必须要考虑同步. 该函数从 map[string]*metricSource 中根据指定的 name 获取一个指向 metricSource 的指针,如果获取不到则创建一个并返回.其中要注意的关键点是我们只会对这个 map 进行插入操作. 简单实现如下:(为节省篇幅,省…
How to Gracefully Close Channels,这篇博客讲了如何优雅的关闭channel的技巧,好好研读,收获良多. 众所周知,在golang中,关闭或者向已关闭的channel发送数据都会引发panic. 谨遵优雅关闭channel的原则 不要在接受一端关闭channel 不要在有多个并发的senders中关闭channel.反过来说,如果只有一个协程充当sender,那么我们可以在这个sender协程内关闭掉channel. 一个简单的方法 SafeClose type M…
from : https://levy.at/blog/11 进阶篇 关闭HTTP的响应 level: intermediate 当你使用标准http库发起请求时,你得到一个http的响应变量.如果你不读取响应主体,你依旧需要关闭它.注意对于空的响应你也一定要这么做.对于新的Go开发者而言,这个很容易就会忘掉. 一些新的Go开发者确实尝试关闭响应主体,但他们在错误的地方做. package main import ( "fmt" "net/http" "i…
并发中超时处理是必不可少的,golang没有提供直接的超时处理机制,但可以利用select机制来解决超时问题. func timeoutFunc() { //首先,实现并执行一个匿名的超时等待函数 timeout := make(chan bool, 1) go func() { time.Sleep(1e9) //等待1秒钟 timeout <- true }() //然后,我们把timeout这个channel利用起来 select { case <- ch: //从ch中读到数据 cas…
原文链接 package main import ( "fmt" "math/rand" "os" "runtime" "sync" "sync/atomic" "time" ) type Scenario struct { Name string Description []string Examples []string RunExample func() } v…
今天是golang专题的第14篇文章,大家可以点击上方的专辑回顾之前的内容. 今天我们来看看golang当中另一个很重要的概念--信道.我们之前介绍goroutine的时候曾经提过一个问题,当我们启动了多个goroutine之后,我们怎么样让goroutine之间保持通信呢? 要回答这个问题就需要用到信道. channel 信道的英文是channel,在golang当中的关键字是chan.它的用途是用来在goroutine之间传输数据,这里你可能要问了,为什么一定得是goroutine之间传输数…
channel是Go语言中的一个核心数据类型,channel是一个数据类型,主要用来解决协程的同步问题以及协程之间数据共享(数据传递)的问题.在并发核心单元通过它就可以发送或者接收数据进行通讯,这在一定程度上又进一步降低了编程的难度. goroutine运行在相同的内存地址空间,channel可以避开所有内存共享导致的坑:通道的通信方式保证了同步性.数据通过channel:同一时间只有一个协程可以访问数据:所以不会出现数据竞争,确保并发安全. channel的定义 channel是对应make创…
同步容器类 早期版本的JDK提供的同步容器类为Vector和Hashtable,JDK1.2 提供了Collections.synchronizedXxx等工程方法,将普通的容器继续包装.对每个共有方法都进行同步. Collection类中提供了多个synchronizedXxx方法,该方法返回指定集合对象对应的同步对象.synchronizedXxx方法本质是对相应容器的包装. 例:使用Collections类获得同步容器. public static void main(String[] a…
CountDownLatch  同步倒数计数器 CountDownLatch是一个同步倒数计数器.CountDownLatch允许一个或多个线程等待其他线程完成操作. CountDownLatch对象内部存有一个整数作为计数器.调用countDown()方法就将计数器减1,当计数到达0时,则所有等待者会停止等待.计数器的操作是原子性的. CountDownLatch类的常用API 构造方法 CountDownLatch(int count)  构造方法参数指定了计数的次数. 方法 void aw…
​本系列文章经补充和完善,已修订整理成书<Java编程的逻辑>,由机械工业出版社华章分社出版,于2018年1月上市热销,读者好评如潮!各大网店和书店有售,欢迎购买,京东自营链接:http://item.jd.com/12299018.html 我们在67节和68节实现了线程的一些基本协作机制,那是利用基本的wait/notify实现的,我们提到,Java并发包中有一些专门的同步工具类,本节,我们就来探讨它们. 我们要探讨的工具类包括: 读写锁ReentrantReadWriteLock 信号量…
在golang中,基本的channel读写操作都是阻塞的,如果你想要非阻塞的,可以使用如下示例: 即只要在select中加入default,阻塞立即变成非阻塞: package main import "fmt" func main() { messages := make(chan string) signals := make(chan bool) select { case msg := <-messages: fmt.Println("received mess…
golang提供内建函数cap用于查看channel缓冲区长度. cap的定义如下: func cap(v Type) int The cap built-in function returns the capacity of v, according to its type: - Array: the number of elements in v (same as len(v)).等同于len - Pointer to array: the number of elements in *v…