美文网首页iOS-SwiftiOS DeveloperiOS 小册
GCD 之多线程并发读写(Barrier Task)

GCD 之多线程并发读写(Barrier Task)

作者: fuyoufang | 来源:发表于2016-12-01 23:58 被阅读499次

使用 Barrier Task 方法

Dispatch Barrier 解决多线程并发读写同一个资源发生死锁。
Dispatch Barrier 可以确保提交的闭包在指定的队列中,在特定的时间端内得到唯一的执行。在所有先于 Dispatch Barrier 提交的任务都完成之后,这个闭包才开始执行。轮到 barrier 提交的闭包时,会执行这个闭包并且确保队列在此过程中不会执行其它任务。barrier 闭包完成后队列恢复。需要注意 dispatch_barrier_async 只在自己创建的队列上有这种作用,在全局并发队列和串行队列上,效果和 dispatch_sync 一样。

事例:高效的防止文件读写冲突

可以创建一个并行队列,操作都在这个队列中进行。没有更新数据的读用并行,而写用串行。这样既可以防止文件读写冲突,有可以提高效率。

//创建队列
_asyncQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

- (NSString *)someString {
    __block NSString *localSomeString = nil;
    dispatch_sync(_asyncQueue, ^{
        localSomeString = _someString;
    });
    return localSomeString;
}

- (void)setSomeString:(NSString *)someString {
    dispatch_barrier_async(_asyncQueue, ^{
        _someString = someString;
    });
}

swift示例

// 创建并行队列
self.asyncQueue = DispatchQueue.global();

var someString: NSString {
    get {
        // 读数据时使用并行
        var localString: NSString!
        self.asyncQueue.async {
            localString = self.someString;
        }
        return localString
    }
    set {
        // 写数据时使用串行
        asyncQueue.sync(flags: .barrier, execute: {
            self.someString = newValue
        });
    }
}

相关文章

网友评论

  • lele8446:并行读部分写错了吧
    - (NSString *)someString {
    __block NSString *localSomeString = nil;
    dispatch_sync(_asyncQueue, ^{
    localSomeString = _someString;
    });
    return localSomeString;
    }
    应该是:
    dispatch_async(_asyncQueue, ^{
    localSomeString = _someString;
    });
    EagleOne:@fuyoufang 那你这没做到并发读啊,兄弟
    fuyoufang:@lele8446 没错的。如果改成你那样写就读不到数据了。

本文标题:GCD 之多线程并发读写(Barrier Task)

本文链接:https://www.haomeiwen.com/subject/kryfmttx.html