在Go语言自带的godoc程序实现中有一个vfs的包对应虚拟的文件系统,在vfs包下面有一个gatefs的子包,gatefs子包的目的就是为了控制访问该虚拟文件系统的最大并发数。gatefs包的应用很简单:
import ( "golang.org/x/tools/godoc/vfs" "golang.org/x/tools/godoc/gatefs" ) func main() { fs := gatefs.New(vfs.OS("/path"), make(chan bool), 8) }
其中vfs.OS("/path")基于本地文件系统构造一个虚拟的文件系统,单后gatefs.New基于现有的虚拟文件系统构造一个并发受控的虚拟文件系统。通过带缓存通道的发送和接受规则来实现最大并发阻塞:
var limit = make(chan int, 3) func main() { for _,w := range work { go func() { limit <- 1 w() <-limit }() } select{} }
不过gatefs对此做一个抽象类型gate,增加了enter()和leave()方法分别对应并发代码的进入和离开。当超出并发数目限制的时候,enter()方法会阻塞直到并发数降下来为止。
type gate chan bool func (g gate) enter() { g <- true} func (g gate) leave() { <- g}
gatefs包装的行的虚拟文件系统就是将需要控制并发的方法增加了对enter()和leave()的调用而已:
type gatefs struct { fs vfs.FileSystem gate } func (fs gatefs) Lstat(p string) (os.FileInfo, error) { fs.enter() defer fs.leave() return fs.fs.Lstat(p) }
我们不仅可以控制最大的并发数目,而且可以通过带缓存通道的使用量和最大容量比例来判断程序运行的并发率。当通道为空时可以认为是空闲状态,当通道满了时可以认为是繁忙状态,这对后台一些低级任务的运行时有参考价值的
有疑问加站长微信联系(非本文作者)