SwiftSafe:并发情况下的数据存取(线程保护)工具库

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友 微信微信
查看查看147 回复回复2 收藏收藏 分享淘帖 转播转播 分享分享 微信
查看: 147|回复: 2
收起左侧

SwiftSafe:并发情况下的数据存取(线程保护)工具库

[复制链接]
jswift 发表于 2016-10-18 12:25:55 | 显示全部楼层 |阅读模式
快来登录
获取最新的苹果动态资讯
收藏热门的iOS等技术干货
拷贝下载Swift Demo源代码

SwiftSafe:并发情况下的数据存取(线程保护)工具库,Thread synchronization made easy.

SwiftSafe:并发情况下的数据存取(线程保护)工具库

SwiftSafe:并发情况下的数据存取(线程保护)工具库 - 敏捷大拇指 - SwiftSafe:并发情况下的数据存取(线程保护)工具库





1、Why?

Performance-sensitive classes need internal state synchronization, so that external accessors don't break the internal invariants and cause race conditions. Using GCD (Grand Central Dispatch) directly can confuse newcomers, because the API doesn't necessarily reflect the actual reason why it's being used. That's why wrapping it in a straighforward Swifty API can introduce a bit more clarity to your code. See examples below.




2、Concurrency modes supported

  • EREW - Exclusive Read, Exclusive Write: The most common synchronization method, where only one thread can read or write your protected resource at one time. One big disadvantage is that it's prone to deadlocks.
  • CREW - Concurrent Read, Exclusive Write: Less common, but IMO more powerful method, where multiple threads can read, but only one thread can write at one time. Reading and writing is automatically made exclusive, i.e. all reads enqueued before a write are executed first, then the single write is executed, then more reads can be executed (those enqueued after the write).





3、Requirements

  • iOS 8.0+
  • Swift 3.0+





4、Installation



4.1、Carthage

[Bash shell] 纯文本查看 复制代码
github "nodes-ios/SwiftSafe" ~> 2.0


For Swift 2.2 release:

[Bash shell] 纯文本查看 复制代码
github "nodes-ios/SwiftSafe" ~> 1.0




4.2、CocoaPods

[Bash shell] 纯文本查看 复制代码
pod 'SwiftSafe'





5、Usage

Let's say you're writing a thread-safe NSData cache. You'd like it to use CREW access to maximize performance.

[Swift] 纯文本查看 复制代码
class MyCache {
    private let storage: NSMutableDictionary = NSMutableDictionary()
    public func hit(key: String) -> NSData? {
        let found = self.storage[key]
        if let found = found {
            print("Hit for key \(key) -> \(found)")
        } else {
            print("Miss for key \(key)")
        }
        return found
    }
    public func update(key: String, value: NSData) {
        print("Updating \(key) -> \(value)")
        self.storage[key] = value
    }
}


This is the first implementation. It works, but when you start calling it from multiple threads at the same time, you'll encounter inconsistencies and race conditions - meaning you'll be getting different results with the same sequence of actions. In more complicated cases, you might even cause a runtime crash.

The way you fix it is obviously by protecting the internal storage (note: NSDictionary is not thread-safe). Again, to be most efficient, we want to allow any number of threads reading from the cache, but only one to update it (and ensure that nobody is reading from it at that time). You can achieve these guarantees with GCD, which is what SwiftSafe does. What this API brings to the table, however, is the simple and obvious naming.

Let's see how we can make our cache thread-safe in a couple lines of code.

[Swift] 纯文本查看 复制代码
import SwiftSafe

class MyCache {
    private let storage: NSMutableDictionary = NSMutableDictionary()
    private let safe: Safe = CREW()
    public func hit(key: String) -> NSData? {
        var found: NSData?
        safe.read {
            found = self.storage[key]
            if let found = found {
                print("Hit for key \(key) -> \(found)")
            } else {
                print("Miss for key \(key)")
            }
        }
        return found
    }
    public func update(key: String, value: NSData) {
        safe.write {
            print("Updating \(key) -> \(value)")
            self.storage[key] = value
        }
    }
}


That's it! Just import the library, create a Safe object which follows the concurrency mode you're trying to achieve (CREW in this case) and wrap your accesses to the shared resource in read and write calls. Note that read closures always block the caller thread, whereas write don't. If you ever have a call which both updates your resource and reads from it, make sure to split that functionality into the writing and reading part. This will make it much easier to reason about and parallelize.




6、Bottom line

Even though it might sound unnecessary to some, understandable and correct methods of synchronization will save you days of debugging and many headaches.




7、Code of Conduct

Please note that this project is released with a Contributor Code of Conduct. By participating in this project you agree to abide by its terms.




8、License

MIT




9、Author

Honza Dvorsky - http://honzadvorsky.com, @czechboy0




转自:Github

都看到这里了,就把这篇资料推荐给您的好朋友吧,让他们也感受一下。

回帖是一种美德,也是对楼主发帖的尊重和支持。

*声明:敏捷大拇指是全球最大的Swift开发者社区、苹果粉丝家园、智能移动门户,所载内容仅限于传递更多最新信息,并不意味赞同其观点或证实其描述;内容仅供参考,并非绝对正确的建议。本站不对上述信息的真实性、合法性、完整性做出保证;转载请注明来源并加上本站链接,敏捷大拇指将保留所有法律权益。如有疑问或建议,邮件至marketing@swifthumb.com

*联系:微信公众平台:“swifthumb” / 腾讯微博:@swifthumb / 新浪微博:@swifthumb / 官方QQ一群:343549891(满) / 官方QQ二群:245285613 ,需要报上用户名才会被同意进群,请先注册敏捷大拇指

嗯,不错!期待更多好内容,支持一把:
支持敏捷大拇指,用支付宝支付10.24元 支持敏捷大拇指,用微信支付10.24元

评分

参与人数 1金钱 +10 贡献 +10 专家分 +10 收起 理由
Anewczs + 10 + 10 + 10 32个赞!专家给力!

查看全部评分

本帖被以下淘专辑推荐:

yadan 发表于 2016-10-18 14:36:59 | 显示全部楼层
GCD
SwiftRobot 发表于 2016-11-9 14:37:27 | 显示全部楼层
好资料!
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

做任务,领红包。
我要发帖

分享扩散

都看到这里了,就把这资料推荐给您的好朋友吧,让他们也感受一下。
您的每一位朋友访问此永久链接后,您都将获得相应的金钱积分奖励
热门推荐

合作伙伴

Swift小苹果

  • 北京治世天下科技有限公司
  • ©2014-2016 敏捷大拇指
  • 京ICP备14029482号
  • Powered by Discuz! X3.1 Licensed
  • swifthumb Wechat Code
  •   
快速回复 返回顶部 返回列表