首页 > 其他分享 >GCD 并发队列来实现多读单写

GCD 并发队列来实现多读单写

时间:2024-03-26 17:12:11浏览次数:23  
标签:单写 GCD NSArray dispatch queue 线程 多读 writeQueue

 

iOS 的多读单写指的是多个线程可以同时读取共享的数据,但是只有一个线程能够写入数据。这是为了保证数据的一致性和避免竞争条件的出现。

一 在 Objective-C 中,可以使用 GCD 的并发队列来实现多读单写。具体实现步骤如下:

1.定义一个并发队列和一个串行队列,用于处理读操作和写操作,分别为 readQueue 和 writeQueue。

dispatch_queue_t readQueue = dispatch_queue_create("com.example.readQueue", DISPATCH_QUEUE_CONCURRENT);
dispatch_queue_t writeQueue = dispatch_queue_create("com.example.writeQueue", DISPATCH_QUEUE_SERIAL);
2.定义一个全局变量,用于存储共享数据。

NSMutableArray *sharedData = [NSMutableArray array];
3.实现读操作,使用 readQueue 中的异步方法来执行读取操作,这样多个读操作可以同时进行。

- (void)readDataWithCompletion:(void (^)(NSArray *))completion {
dispatch_async(readQueue, ^{
NSArray *dataArray = [NSArray arrayWithArray:sharedData];
dispatch_async(dispatch_get_main_queue(), ^{
completion(dataArray);
});
});
}
4.实现写操作,使用 writeQueue 中的同步方法来执行写入操作,这样保证只有一个线程能够写入数据

- (void)writeData:(id)data {
dispatch_sync(writeQueue, ^{
[sharedData addObject:data];
});
}
通过以上步骤,我们实现了多读单写的功能,多个线程可以同时读取共享数据,但是只有一个线程能够写入数据。这样可以保证数据的一致性和避免竞争条件的出现。注意在 Objective-C 中需要使用 block 来传递回调函数,以及使用 dispatch_get_main_queue() 来将结果回调到主线程。

二 使用 dispatch_barrier_async 函数 并发队列

dispatch_queue_t queue = dispatch_queue_create("com.example.queue", DISPATCH_QUEUE_CONCURRENT);
NSMutableArray *array = [NSMutableArray array];

- (void)write:(id)value {
dispatch_barrier_async(queue, ^{
[array addObject:value];
});
}

- (NSArray *)read {
__block NSArray *result = nil;
dispatch_sync(queue, ^{
result = [array copy];
});
return result;
}
————————————————

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。

原文链接:https://blog.csdn.net/lvlemo/article/details/130069488

标签:单写,GCD,NSArray,dispatch,queue,线程,多读,writeQueue
From: https://www.cnblogs.com/huangzs/p/18097109

相关文章

  • 扩展欧几里得(exgcd)通解及其证明
    exgcd求ax+by=gcd(a,b)中x和y的通解(下面简称通解)什么是通解我们知道二元一次方程,是如果只有一个式子,那么解会有无数个而通解就是指让我们只找到一个解就可以推出其他所有解的式子(注意本证明极其复杂,请直接背模版或感性理解)知道了定义下面就是推式子了首先......
  • CF1945 H GCD is Greater
    CF1945HGCDisGreater什么鬼啊div3Hdiff:2775。纯属码力题。首先发现\(\gcd\)肯定数字越多越小。然后与值数字越多越小。所以结论就是选择两个数字取\(\gcd\),剩下的数字分到另一个集合。那么问题就变成了找出一对数字,它们的\(\gcd\)和剩下的数字的与做差值最大......
  • CodeForces 1945H GCD is Greater
    洛谷传送门CF传送门感觉是这场唯一比较有趣的题?首先明确一点:先手只会选\(2\)个数,因为数多了\(\gcd\)会变小,而且对方的\(\text{and}\)会变大。所以对于某一位,若\(0\)的个数\(\ge3\)那么对方的按位与这一位一定是\(0\)。所以若\(0\)的个数\(\le2\),那么可能会......
  • P5656 【模版】二元一次不定方程(exgcd)
    综合考查exgcd功力的题目。没有整数解当且仅当\(\gcd(a,b)\nmidc\),直接输出-1。用exgcd解方程\(ax+by=\gcd(a,b)\)得到一组特解\(x_0,y_0\)。对原方程变形得到\(a\cdot\dfrac{xc}{\gcd(a,b)}+b\cdot\dfrac{yc}{\gcd(a,b)}=c\),于是有\(ax+by=c\)的一组特解\(x_1=\d......
  • GCDAsyncSocket_Reference
    原文:https://github.com/robbiehanson/CocoaAsyncSocket/wiki/Reference_GCDAsyncSocketGCDAsyncSocket是基于GrandCentralDispatch构建的TCP套接字网络库。该项目还包含一个基于RunLoop的版本,以及UDP套接字库。CocoaAsyncSocket项目是一个成熟的开源框架,自2003......
  • 3101: *【莫比乌斯反演:练习】gcd(i,j)=k的对数[POI2007]ZAP-Queries
    问题给出\(n,m,k\)(\(1\leqn,m,k\leq10^5\)),求\(\sum\limits_{i=1}^n\sum\limits_{j=1}^m\lbrack\gcd(i,j)=k\rbrack\),即:满足\(1\leqi\leqn\),\(1\leqj\leqm\),且\(\gcd(i,j)=k\)的二元组\((i,j)\)的数量。题解\(\sum\limits_{i=1}......
  • Interval GCD 题解
    题目描述给定一个长度为\(\largen\)的数组\(\largea\),以及\(\largem\)条指令(\(n\leq5\times10^5,m\leq10^5\)),每条指令可能是以下两种之一:“\(\large\operatorname{C\l\r\d}\)”,表示把\(\largea[l],a[l+1],…,a[r]\)都加上\(\larged\)。“\(\large\operatorn......
  • Small GCD
    有两种做法第一种做法:欧拉反演(其实我赛时的时候是想到了欧拉反演的,但是我不太清楚欧拉反演的使用trick)欧拉反演的trick见这篇文章欧拉反演直接用在gcd上还是挺多的,可以想一下\(cnt\)数组怎么求\(cnt\)数组其实是只用记一维的(因为记两维肯定爆炸了)。考虑对于\(d\),如果\(d\)不是......
  • lcm(a,b)=a*b/gcd(a,b)
    求俩组爆int的数据的最小公倍数lcm等价于求这俩个数的最大公因数gcd即lcm(a,b)=a*b/gcd(a,b)求俩组爆int数据的最大公因数可以使用辗转相除法`include<bits/stdc++.h>usingnamespacestd;typedeflonglongll;llgcd(llda,llxiao){inttemp;while(xiao!=0){temp......
  • 「UR#2」树上 GCD
    题目链接。讲的是一个较劣的做法。先转换成求\(\gcd\)为\(d\)倍数的种数。考虑无脑上根号分治。设阈值为\(B\),我们对不超过\(B\)的\(d\)暴力求。怎么求呢?我们有一个十分巧妙的方法,记录每个点子树与它距离为\(d\)的倍数的节点数,这样直接树上乱做一下就可以了,答案也是......