Tag: 并发

iOS GCD自定义并发队列执行顺序

根据苹果的文件,我对这个问题有疑问 并发并发队列(也称为全局调度队列)同时执行一个或多个任务, 但是任务仍然按照它们被添加到队列的顺序启动。 当前正在执行的任务在由调度队列pipe理的不同线程上运行。 在任何给定点执行的任务的确切数量是可变的,并取决于系统条件。 在iOS 5及更高版本中,您可以通过将DISPATCH_QUEUE_CONCURRENT指定为队列types来自己创build并发调度队列。 此外,还有四个预定义的全局并发队列供您的应用程序使用。 有关如何获取全局并发队列的更多信息,请参阅获取全局并发调度队列。 我做了一个testing,使用示例代码, dispatch_queue_t concurrentQueue; concurrentQueue = dispatch_queue_create("com.gcd.concurrentQueue", DISPATCH_QUEUE_CONCURRENT); dispatch_async(concurrentQueue, ^{ NSLog(@"First job "); }); dispatch_async(concurrentQueue, ^{ NSLog(@"Second job"); }); dispatch_async(concurrentQueue, ^{ NSLog(@"Third job "); }); 但是结果似乎并不像它们被添加的顺序,这里是结果, 2015-06-03 18:36:38.114 GooglyPuff[58461:1110680] First job 2015-06-03 18:36:38.114 GooglyPuff[58461:1110682] Third job 2015-06-03 18:36:38.114 GooglyPuff[58461:1110679] Second job 所以我的问题是,不应该是第一,第二,第三? 欢迎任何build议,并感谢您的帮助。

从asynchronousWeb服务响应更新托pipe对象的最佳方法?

我有一个NSManagedObjectContext关联到主线程( mainContext ),在那里我获取我显示整个应用程序的所有NSManagedObject 。 用户不要编辑这些对象,但我从Web服务获取更新。 我定期对这些服务执行asynchronous调用,并且“告诉”我要删除哪些pipe理对象(如果有的话),哪些必须用新信息更新(如果有的话),以及是否需要插入新的对象。 所以,我需要首先获得所有服务的响应,然后检查我必须对我的mainContext已有的托pipe对象所做的更改。 而且我还需要执行更新以避免阻止UI。 我正在考虑两种方法来pipe理这种情况: 在私有队列中使用一个完全独立的privateContext和它自己的核心数据栈来插入所有从服务中获得的对象。 然后以某种方式(如何?)与mainContext的对象进行比较,并删除/修改/插入mainContext对象。 在专用队列中使用privateContext ,但是作为mainContext的子mainContext 。 然后,我需要传递子对象的父对象mainContext中的对象(这是可能的?如何?),同时在这个子对象中插入从服务获得的对象,然后比较和执行更改。 哪些方法是最好的或适当的? 或者,也许应该是一个我没有想过的不同的? 提前致谢 编辑:这可能是另一种可能的方式? 只使用mainContext ,而我正在parsing服务的响应,而不是创build新的对象,只需要在mainContext逐一进行更改… 编辑2:另一种可能性? 只有使用privateContext ,获取服务响应并创build新的对象。 然后,也可以用这个privateContext获取所有已经存在的对象(和mainContext的对象一样)。 在这个privateContext比较两组对象(最近创build的服务和获取的),保存此上下文,清除mainContext并重新获取mainContext所有对象。

dispatch_sync(dispatch_get_global_queue(xxx),任务)同步或asynchronous

正如苹果的文档所说,dispatch_get_global_queue()是一个并发队列,dispatch_sync是串行的意思。那么这些任务是asynchronous还是同步?

在iOS中联锁的操作?

iOS SDK中是否存在互锁(primefaces)操作? 我需要联锁增量\减量和互锁比较。 * 更新:*我的主要问题是等待几个主线程创build的NSThreads(主线程不能工作,而其他线程工作)。 我不知道该怎么做

NSFetchedResultsController在合并“NSManagedObjectContextDidSaveNotification”后没有显示所有结果

我有一个NSFetchedResultsController用谓词获取对象: isTrash == NO 大多数情况下,这是按预期工作的,但是当一个对象被取消时,取出的结果控制器不会取出这个未被分离的对象。 怎么了?

如何修改自定义GCD队列的优先级?

我创build了这样的GCD队列: dispatch_queue_t q = dispatch_queue_create("com.testcompany.myqueue", NULL); 当我将任务派送到该队列时,比在主线程上执行任务要慢。 dispatch_async(q, ^(void) { [self performHeavyCalculationAndUpdateUI]; }); 我怀疑这个队列的默认优先级很低。 我怎样才能改变这个队列的优先级? 还是有什么我必须做的?

在不同的线程上调用我的方法有哪些不同的方法?

我有一些数据计算方法(让它是“myMethod:”),我想移动到另一个线程的调用,因为我不想阻止我的主要用户界面function。 所以,开始做一些关于如何在另一个线程上调用我的方法的研究。 据我所知,目前有很多不同的方法来做到这一点。 这是一个列表: a)使用纯线程(可用于iOS 2.0): [NSThread detachNewThreadSelector:@selector(myMethod:) toTarget:self withObject:_myParamsArray]; b)使用简单的快捷方式(从iOS 2.0开始可用)。 可用于inheritance的NSObject,但该方法也属于NSThread类: [self performSelectorInBackground:@selector(myMethod:) withObject:_myParamsArray]; c)使用Grand Central Dispatch队列的新方法(从iOS 4.0开始): dispatch_async(dispatch_get_global_queue(0, 0), ^ { [self myMethod:_myParamsArray]; }); d)不知何故,使用一些类,如NSOperation,NSBlockOperation或NSOperationQueue,虽然不知道该怎么做(一些例子,将不胜感激) 目前,我曾经用过“b”这个案例,但是对这个利弊感兴趣,还有其他相关的build议。 更新:e)也发现了另一种执行类似线程的东西 – 运行循环 。 以下是苹果文档摘录: 运行循环是一个事件处理循环,用于安排工作和协调收到的事件。 运行循环的目的是在有工作要做的时候保持你的线程忙,当没有时候让线程进入睡眠状态。 恕我直言,或多或less你正在处理相同的任务 – 如何调用你的方法在单独的线程进行asynchronous操作。 更新2:已经有了NSInvocationOperation和NSOperationQueue和恕我直言的一些经验,这是相当方便的。 根据苹果文档,GCD和NSOperations是实现multithreading的首选方式。 而且,NSOperations从iOS 4.0开始运行在GCD上。 简而言之,你实例化NSIvocationOperation(作为你的方法的调用),然后实例化NSOperationQueue并将调用添加到队列中。 NSOperationQueue足够聪明,你可以将多个NSIvocationOperation对象(包装你的方法调用)和它们实例化到NSOperationQueue。 剩下的就放心了。 NSOperationQueue确定需要多less个并行线程来执行调用(NSInvocationOperation)并为您处理。 它可以在线程A上执行第一个调用,然后在线程B上执行第一个调用,在线程C上执行第三个,然后执行在线程B上,所以你不必担心这个问题。 但是,如果你想,你可以告诉NSOperationQueue最大的线程可以用来执行调用(例如1),但我没有这个需要。 默认情况下,所有的任务都是在主线程以外的地方执行的,所以操作队列默认是asynchronous的。 另外,如果你想在一个严格队列中执行你的方法调用(每个包装在单独的NSInvocationOperation中),那么你可以添加依赖关系,所以NSOperationQueue将保留方法调用顺序。 这是一个例子: // wrap your […]

使核心数据线程安全

长话短说,我厌倦了与NSManagedObjectContext相关的荒谬的并发规则(或者说,它完全不支持并发性,倾向于爆炸或做其他不正确的事情,如果你试图跨线程共享一个NSManagedObjectContext ),我试图实现一个线程安全的变体。 基本上我所做的是创build一个跟踪它创build的线程的子类,然后将所有方法调用映射回该线程。 这样做的机制有点复杂,但其关键是我有一些帮助方法,如: – (NSInvocation*) invocationWithSelector:(SEL)selector { //creates an NSInvocation for the given selector NSMethodSignature* sig = [self methodSignatureForSelector:selector]; NSInvocation* call = [NSInvocation invocationWithMethodSignature:sig]; [call retainArguments]; call.target = self; call.selector = selector; return call; } – (void) runInvocationOnContextThread:(NSInvocation*)invocation { //performs an NSInvocation on the thread associated with this context NSThread* currentThread = [NSThread currentThread]; […]

用于保存核心数据的NSPersistentContainer并发性

我已经阅读了一些关于这个的博客,但是我仍然对如何使用NSPersistentContainer performBackgroundTask创build实体并保存它感到困惑。 通过在performBackgroundTask() { (moc) in }块中调用便利方法init(context moc: NSManagedObjectContext)创build一个实例后,如果我检查container.viewContext.hasChanges这将返回false,并说没有什么可以保存,如果我调用保存moc (为这个块创build的背景MOC)我得到像这样的错误: fatal error: Failure to save context: Error Domain=NSCocoaErrorDomain Code=133020 "Could not merge changes." UserInfo={conflictList=( "NSMergeConflict (0x17466c500) for NSManagedObject (0x1702cd3c0) with objectID '0xd000000000100000 <x-coredata://3EE6E11B-1901-47B5-9931-3C95D6513974/Currency/p4>' with oldVersion = 1 and newVersion = 2 and old cached row = {id = 2; … }fatal error: Failure to save […]

使用dispatch_group_async的并发代码的性能比单线程版本慢得多

最近我一直在做大量的随机数生成“正态分布”钟形曲线的实验。 方法很简单: 创build一个整数数组并将其归零。 (我使用2001整数) 重复计算该数组中的索引,并将该数组中的条目编入索引,如下所示 循环999或1000次。 在每次迭代中: 以中心值(1000)为数组索引 生成一个随机数= + 1 / -1。 并将其添加到数组索引 在循环结束时,在计算的数组索引处增加值。 由于随机值0/1倾向于频繁出现,因此上面内部循环的结束索引值倾向于保持接近中心值。 比起始值大得多/小得多的指标值越来越不寻常。 在大量重复之后,数组中的值呈现正态分布钟形曲线的形状。 然而,我使用的高质量的随机函数arc4random_uniform()相当慢,并且需要很多迭代才能生成平滑的曲线。 我想计划10亿(十亿)点。 在主线程上运行,大约需要16个小时。 我决定重写计算代码来使用dispatch_async,并在我的8核心Mac Pro上运行它。 我结束了使用dispatch_group_async()提交8个块,dispatch_group_notify()在所有块完成处理时通知程序。 为了简化第一遍,所有8个块写入相同的NSUInteger数组。 在读取/修改写入数组条目时,出现竞争条件的可能性很小,但是在这种情况下,这只会导致一个值丢失。 我正打算在稍后添加一个锁到数组增量(或者甚至可以在每个块中创build单独的数组,然后将它们相加)。 无论如何,我重构代码使用dispatch_group_async()并计算每个块中的总值的1/8,并设置我的代码运行。 对我来说,并发代码尽pipe最大化了我Mac上的所有内核,但运行速度比单线程代码慢。 单线程运行时,每秒可以得到大约17,800个点。 当使用dispatch_group_async运行时,性能下降到更像665点/秒,或约1/26的速度 。 我已经改变了我提交的块数 – 2,4或8,没关系。 性能是可怕的。 我也尝试使用dispatch_async提交所有8个块,没有dispatch_group。 这也没有关系。 目前没有阻塞/locking正在进行:所有块全速运行。 对于为什么并发代码运行速度慢,我感到十分困惑。 现在的代码有点混乱,因为我重构了它的单线程或同时工作,所以我可以testing。 以下是运行计算的代码: randCount = 2; #define K_USE_ASYNC 1 #if K_USE_ASYNC dispatch_queue_t highQ = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0); […]