Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
iOS-NSCache如何确保线程安全_Ios_Multithreading_Thread Safety_Nscache - Fatal编程技术网

iOS-NSCache如何确保线程安全

iOS-NSCache如何确保线程安全,ios,multithreading,thread-safety,nscache,Ios,Multithreading,Thread Safety,Nscache,我想实现一个线程安全的MutableDataContainer。当然,我可以简单地为写和读操作添加一个锁,但是在我的项目中,我需要频繁地读取数据,所以我不想使用这种方法 有人知道NSCache是如何实现的吗?我不完全确定NSCache具体使用的锁定机制,但我建议在苹果平台的现代开发中特别推荐5种解决方案之一,这可能是NSCache实现的方式之一。可能有5种以上,此列表并不详尽。我只是不包括更多,因为在我看来,我不相信苹果会使用这里没有包括的方法 以下所有方法都有效,但我会尽量避免让人觉得我对哪种

我想实现一个线程安全的
MutableDataContainer
。当然,我可以简单地为写和读操作添加一个锁,但是在我的项目中,我需要频繁地读取数据,所以我不想使用这种方法


有人知道NSCache是如何实现的吗?

我不完全确定NSCache具体使用的锁定机制,但我建议在苹果平台的现代开发中特别推荐5种解决方案之一,这可能是NSCache实现的方式之一。可能有5种以上,此列表并不详尽。我只是不包括更多,因为在我看来,我不相信苹果会使用这里没有包括的方法

以下所有方法都有效,但我会尽量避免让人觉得我对哪种方法更好(我们会看看结果),因为这不是你的问题的真正内容。此外,在这个问题上有许多观点,我不想煽风点火。我将要讨论的是,基于这些方法和我对苹果的看法,提供我对NSCache实现方式的看法

  • pthread库的pthread RW锁。这是专门为同步而设计的,并且具有锁所能提供的与简单互斥锁不同的性能(RW锁实际使用的是什么)。对于读取,使用
    pthread\u rwlock\u rdlock
    获得锁;对于写入,使用
    pthread\u rwlock\u wrlock
    获得锁。在下面,这本质上是一个递归锁,在有写操作之前,不应该实际阻止读取。这优化了较常见的读取路径,并安全地考虑了较不常见的写入路径。对于更不常见的读/写操作,基本上必须将其升级为写操作。当使用pthread锁(或互斥锁)时,您可以根据自己代码的逻辑和内部良好定义的条件来优化锁定,尽管我在这里不赘述

  • GCD库的串行队列-在使用串行队列时,您使用
    disaptch\u sync
    进行读取,使用
    dispatch\u async
    进行写入。这与优化公共路径的pthread RW锁不同,因为读写都是串行的。尽管它确实依赖于GCD通过其基础队列优化来优化读取(例如,GCD确定何时为
    dispatch\u sync
    调用进行适当的阻塞)。对于更不常见的读/写操作,只需将其视为读操作并使用
    dispatch\u sync
    。这也是,因为这种方法与之前的方法有一个重要的区别,即尽管读取应该通过GCD进行快速和优化,但它们仍然是串行的,在技术上仍然相互阻塞

  • GCD库的并发队列-在使用并发队列时,您可以使用
    dispatch\u sync
    进行读取,使用
    dispatch\u barrier\u async
    进行写入。对于读/写的特殊情况,几乎专门为此目的制作了
    dispatch\u barrier\u sync
    。在这个世界上,读永远不会相互阻塞,并且在它们碰到为写和读/写保留的屏障之前根本不会阻塞。这种方法还依赖于GCD来优化读取,但通过使用并发队列,您可以选择不进行串行读取。因此,基本上由您来控制必须是串行的事情,并在这些操作需要时使用屏障

  • <> >基础框架的<代码> NSLock < /代码>——这是基础框架的经典构造。虽然它最初的实现可能不同,但最近我研究了它的内部构造,在我测试过的所有案例中,它本质上是一个围绕相应pthread实现的Objective-C包装器

  • Objective-C的
    @synchronized()
    -这是一个内置的Objective-C函数/关键字,提供锁定和异常处理。它的底层本质上是一个带有异常处理程序的NSLock。当使用它时,它同时用于读取和写入。在内部,它们被视为相同的,因此没有针对其中一个进行优化。您的锁与传递给
    @synchronized(obj)
    函数的对象相关联。因此,本质上,您是锁定对该对象的访问,而不管它在相应的``@synchronized(){}`块中如何使用或变异

  • 每种方法都有更多的细节和注意事项,但如果我是一个赌徒(我不是),并且基于我在这之后将要讨论的几件事,我会说苹果正在使用方法3来进行NSCache

    理由1:苹果关注业绩,尤其是基金会。自GCD成立以来,他们就在GCD上投入了大量资金,并在继续投资。创建GCD的大多数原因都是基于在不牺牲性能的情况下尽可能多地删除样板文件。我想说,苹果可能是狗狗,他们在基金会内部的一些地方提出了建议,NSCACH可能是其中之一。p>
    原因2:类似于“原因1继续”,最近有更多证据表明苹果在GCD上的投资以及在
    @synchonized()
    上的投资不足,这可以从Swift中看出。GCD是Swift中同步的首选方法。

    锁定读取操作的原因是什么?只需锁写另一个无锁的想法是将所有操作包装在一个序列中queue@sage444我可以在一个队列中写入数据,但可以在每个队列中调用读取操作。如果我不锁定读取,则在重写数据时读取数据可能会崩溃。看起来NSCache的快速实现使用了旧的普通NSLock:@mojuba,dead link:(@ScottyBlades他们稍微更改了路径:哦..很棘手…谢谢!旧的普通NSLock也==pthread mutex