GCDdispatch_barrier还是dispatch_sync?

2024-05-03

我有一些疑问dispatch_barrier and dispatch_sync。 这是代码:

- (void)addPhoto:(Photo *)photo
{
    if (photo) { // 1
        dispatch_barrier_async(self.concurrentPhotoQueue, ^{ // 2 
            [_photosArray addObject:photo]; // 3
            dispatch_async(dispatch_get_main_queue(), ^{ // 4
                [self postContentAddedNotification]; 
            });
        });
    }
}

- (NSArray *)photos
{
    __block NSArray *array; // 1
    dispatch_sync(self.concurrentPhotoQueue, ^{ // 2
        array = [NSArray arrayWithArray:_photosArray]; // 3
    });
    return array;
}

In addPhoto方法,它使用dispatch_barrier_async. In photos方法,它使用dispatch_sync。我可以更换吗dispatch_barrier_async into dispatch_sync?如果是的话,这种方式在实际编程中流行吗?如果不是,请告诉我原因。多谢!


实际上,在这个例子中,替换dispatch_barrier_async with dispatch_sync会产生意想不到的行为。您有并发队列来访问照片 - 这意味着,它可以让您同时运行多个操作。读书没问题_photosArray一次从任意多个地方出发。但是,如果您在有人阅读它的同时尝试更改其内容,就会发生不好的事情。来了dispatch_barrier_async- 可以这么说,它可以让您将“串行性”添加到并发队列中。以这种方式分派的块将等待,直到所有其他操作停止、启动,并且在执行时没有人会在该队列上启动任何操作。

很经典读者-作者问题 https://en.wikipedia.org/wiki/Readers%E2%80%93writers_problem.

如果有什么无法解释的地方,请随时询问

Update 1

你不能使用async功能于photos方法。dispatch_sync使您的方法等待任务执行。

我用数字标记了执行流程

- (NSArray *)photos
{
    __block NSArray *array; //1. Here array is nil
    dispatch_sync(self.concurrentPhotoQueue, ^{ //2. dispatch task and wait it ends execution
        array = [NSArray arrayWithArray:_photosArray]; //3. Array filled with photos
    });

    return array; //4. Array filled with photos
}

如果你使用async

- (NSArray *)photos
{
    __block NSArray *array; //1. Here array is nil
    dispatch_async(self.concurrentPhotoQueue, ^{ //2. dispatch task and move on
        array = [NSArray arrayWithArray:_photosArray]; //4. Array filled with photos
    });

    return array; //3. Array is still nil
}

Update 2

Several dispatch_sync呼叫将同时运行。

例如,你有thread1 and thread2。他们持有同一个物体object。在某些地方他们同时打电话

thread1 : NSLog(@"%@", [object photos]); thread2 : NSArray *photos = [object photos];

此调用将同时执行(即在同一时间),但同步执行 - 线程冻结直到获取照片。

但是,如果你做了这样的事情

thread2 : NSArray *photos = [object addPhoto:newPhoto]; thread1 : NSLog(@"%@", [object photos]);

your thread1冻结直到照片添加到数组中。但,thread2不会等待,直到照片实际添加 - 它只是继续执行。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

GCDdispatch_barrier还是dispatch_sync? 的相关文章

  • DispatchQueue 同步并发

    好吧 我已经经历了大量的问题和答案 并且我知道对其的理解 但是当我尝试一些代码时 我得到的结果并不支持这些理论 到目前为止我所理解的 同步 一旦块内的所有任务都被执行 控制就会返回 异步 控制将在块被击中后立即返回 这是看起来不错的部分 现
  • 如何安排一个块在下一次运行循环迭代中运行?

    我希望能够执行block在下一次运行循环迭代中 它是在下一个运行循环的开始还是结束时执行并不那么重要 只是执行会推迟到当前运行循环中的所有代码都完成执行为止 我知道以下内容不起作用 因为它与主运行循环交错 因此我的代码可能会在下一个运行循环
  • 类型“DispatchQueue.Attributes”没有成员“serial”

    我已经使用 Xcode8 beta4 将现有的 Swift2 3 代码转换为 Swift3 0 Xcode自动将语法转换为Swift3 0 但它无法创建串行调度队列 private let serialQueue DispatchQueue
  • 如何在主队列上同步调度而不发生死锁?

    我需要在主队列上同步调度一个块 我不知道我当前是否在主线程上运行 天真的解决方案如下所示 dispatch sync dispatch get main queue block 但是 如果我当前位于主队列上运行的块内 则此调用会造成死锁 同
  • swift 中 DispatchQueue 类型之间的区别

    据我了解 Swift 中有 3 种类型的 DispatchQueue 主要 连续剧 主线 全球 并发 后台线程并行工作 自定义 并发或串行 每一个都可能有效 异步或同步 第一个问题 主队列是否在工作仅 UI 线程并且不在另一个线程上工作 如
  • 是否dispatch_async(dispatch_get_main_queue(), ^{...});等到完成?

    我的应用程序中有一个场景 我想在一个方法中执行一些耗时的任务 其中包括一些数据处理和 UI 更新 我的方法看起来像这样 void doCalculationsAndUpdateUIs DATA PROCESSING 1 UI UPDATE
  • 在 Swift 中使用 AWSTask 对象的正确方法是什么?

    您好 提前感谢您的宝贵时间 在我的代码中 我向 AWSSQS 发出各种请求 这些请求都返回 AWSTask 我发现使用这些 AWSTask 对象非常困难 同时还试图将特定于 AWS 的所有逻辑保留在单个类中 以便我可以在需要时轻松切换到不同
  • Swift UI 被高频 @StateObject 更新淹没了吗?

    Scenario 一个简单的 SwiftUIApp由一个TabView有两个选项卡 这App结构体有一个 StateObject属性 该属性正在重复且非常快速地 每秒 30 次 更新simulateFastStateUpdate 在这个例子
  • 如何使用dispatch_async_f?

    我想要排队的函数不带参数 我传递什么paramContext 传入 NULL 会生成编译错误 无效使用 void 表达式 我不想只是为了编译而向我的函数添加参数 我该如何使其工作 Mac OS X Snowleopard 带有 Object
  • C++11 随机数生成器的线程安全

    C 11 中有许多新的随机数生成器引擎和分布函数 它们线程安全吗 如果您在多个线程之间共享单个随机分布和引擎 是否安全并且您仍然会收到随机数吗 我正在寻找的场景是这样的 void foo std mt19937 64 engine stat
  • GCD和回调-并发问题

    我注册了一个回调处理程序 用于侦听 iOS 地址簿中的更改 由于某些奇怪的原因 已提交错误 当应用程序从后台返回时 有时会多次调用此回调 我希望我的回调处理程序只运行一次逻辑 即使回调被多次调用 这就是我注册回调的方式 ABAddressB
  • 如何使用dispatchQueue创建引用循环?

    我觉得我一直误解了创建引用循环的时间 在我以前认为几乎任何有块并且编译器都会强迫你编写的地方 self那么这是我正在创建引用循环并且需要使用的标志 weak self in 但以下设置不会创建引用循环 import Foundation i
  • 如何在 Swift 中实现线程安全哈希表(PhoneBook)数据结构?

    我正在尝试实现一个线程安全的 PhoneBook 对象 电话簿应该能够添加一个人 并根据姓名和电话号码查找一个人 从实现的角度来看 这仅涉及两个哈希表 一个关联名称 gt 人员 另一个关联电话 gt 人员 需要注意的是我希望这个对象是线程安
  • GCDdispatch_barrier还是dispatch_sync?

    我有一些疑问dispatch barrier and dispatch sync 这是代码 void addPhoto Photo photo if photo 1 dispatch barrier async self concurren
  • 使用单个共享后台线程进行 iOS 数据处理?

    我有一个应用程序 可以从网络下载大量资源 并对每个资源进行一些处理 我不希望这项工作发生在主线程上 但它非常轻量级且优先级低 因此所有这些都可以真正发生在同一个共享工作线程上 这似乎是一件好事 因为设置和拆除所有这些工作线程都需要工作 没有
  • dispatch_write() 和dispatch_read() 用法

    我只是在玩一些 GCD 函数来向文件写入和读取数据 其中两个函数是dispatch write and dispatch read 它允许向文件描述符写入和读取数据 而无需设置新的dispatch io t渠道 所以 我有以下代码 impo
  • 使用GCD实现并发读独占写模型

    我试图了解使用 Grand Central Dispatch GCD 实现控制资源访问的并发读独占写模型的正确方法 假设有一个 NSMutableDictionary 被大量读取并且偶尔更新 确保读取始终与字典状态一致的正确方法是什么 当然
  • Swift 3 GCD API 更改后的dispatch_once

    新语法是什么dispatch once在语言版本 3 中进行更改后的 Swift 中 旧版本如下 var token dispatch once t 0 func test dispatch once token These 对 libdi
  • NSNotification 与dispatch_get_main_queue

    和 关联这个问题 https stackoverflow com questions 7905192 iphone grand central dispatch main thread我想知道关于何时使用 NSNotification 在主
  • 为什么我们不能在当前队列上使用dispatch_sync?

    我遇到了一个场景 我有一个委托回调 它可能发生在主线程或另一个线程上 并且直到运行时我才知道是哪个 使用StoreKit framework 我还需要在该回调中更新 UI 代码 该回调需要在函数执行之前发生 所以我最初的想法是拥有一个如下所

随机推荐