9.7 示例:并发非阻塞缓存

在本节中,我们会创建一个并发非阻塞的缓存系统,它能解决在并发实战很常见但已有的库也不能很好地解决的一个问题:函数记忆(memoizing)[1]问题,即缓存函数的结果,达到多次调用但只须计算一次的效果。我们的解决方案将是并发安全的,并且要避免简单地对整个缓存使用单个锁而带来的锁争夺问题。

我们将使用下面的httpGetBody函数作为示例来演示函数记忆。它会发起一个HTTP GET请求并读取响应体。调用这个函数相当昂贵,所以我们希望避免不必要的重复调用。

最后一行略有一些微妙,ReadAll返回两个结果,一个[]byte和一个error,因为它们分别可以直接赋给httpGetBody声明的结果类型interface{}和一个error,所以我们可以直接返回这个结果而不用做额外的处理。httpGetBody选择这样的结果类型是为了满足我们要做的缓存系统的设计。

下面是缓存的初始版本:

一个Memo实例包含了被记忆的函数f(类型为Func),以及缓存,类型为从字符串到result的一个映射表。每个result都是调用f产生的结果对:一个值和一个错误。在设计的推进过程中我们会展示Memo的几种变体,但所有变体都会遵守这些基本概念。 ...

Get Go程序设计语言 now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.