1、简述
1.1、多线程操作中必然会涉及到锁的概念,使用锁来确保线程安全;
1.2、事实上某些操作,比如数据读取是可以允许多线程同时操作的;
1.3、但写操作不行,数据写入动作必须是同步的,否则会出现数据错误;
1.4、如果读、写操作动作同时发生,并且多线程并发操作时该如何处理?
1.5、通过普通加锁实现线程同步,这样线程是安全了,但影响了读取的效率;
1.6、基本思路是
1.6.1、允许读取操作多线程并发进行;
1.6.2、写入操作只能单个线程同步进行;
1.7、常用的解决方案有两个
1.7.1、pthread_rwlock
1.7.2、dispatch_barrier_async
2、代码示例
2.1、pthread_rwlock
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | #import "ViewController.h" #import <pthread.h> @interface ViewController() { pthread_rwlock_t _rwlock; } @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; pthread_rwlock_init(&_rwlock, NULL); for (int i = 0; i < 10; i++) { dispatch_async(dispatch_get_global_queue(0, 0), ^{ [self read]; }); dispatch_async(dispatch_get_global_queue(0, 0), ^{ [self write]; }); } } - (void)read { pthread_rwlock_rdlock(&_rwlock); sleep(1); NSLog(@"read..."); pthread_rwlock_unlock(&_rwlock); } - (void)write { pthread_rwlock_wrlock(&_rwlock); sleep(1); NSLog(@"write..."); pthread_rwlock_unlock(&_rwlock); } @end |
执行结果:
2018-11-28 14:40:42.959452+0800 MultiThread[11616:2172598] read... 2018-11-28 14:40:43.964333+0800 MultiThread[11616:2172597] write... 2018-11-28 14:40:44.969387+0800 MultiThread[11616:2172599] read... 2018-11-28 14:40:45.974642+0800 MultiThread[11616:2172673] write... 2018-11-28 14:40:46.975541+0800 MultiThread[11616:2172674] read... 2018-11-28 14:40:47.979765+0800 MultiThread[11616:2172675] write... 2018-11-28 14:40:48.982189+0800 MultiThread[11616:2172676] read... 2018-11-28 14:40:49.986234+0800 MultiThread[11616:2172677] write... 2018-11-28 14:40:50.990627+0800 MultiThread[11616:2172678] read... 2018-11-28 14:40:51.995698+0800 MultiThread[11616:2172679] write... 2018-11-28 14:40:53.000450+0800 MultiThread[11616:2172680] read... 2018-11-28 14:40:54.004271+0800 MultiThread[11616:2172681] write... 2018-11-28 14:40:55.007637+0800 MultiThread[11616:2172682] read... 2018-11-28 14:40:56.010467+0800 MultiThread[11616:2172683] write... 2018-11-28 14:40:57.016078+0800 MultiThread[11616:2172684] read... 2018-11-28 14:40:58.018431+0800 MultiThread[11616:2172685] write... 2018-11-28 14:40:59.024275+0800 MultiThread[11616:2172687] write... 2018-11-28 14:41:00.029617+0800 MultiThread[11616:2172686] read... 2018-11-28 14:41:00.029645+0800 MultiThread[11616:2172688] read... 2018-11-28 14:41:01.034141+0800 MultiThread[11616:2172689] write... |
2.2、dispatch_barrier_asyn
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | #import "ViewController.h" #import <pthread.h> @interface ViewController() { dispatch_queue_t _queue; } @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; _queue = dispatch_queue_create("rw_queue", DISPATCH_QUEUE_CONCURRENT); for (int i = 0; i < 10; i++) { dispatch_async(dispatch_get_global_queue(0, 0), ^{ [self read]; }); dispatch_async(dispatch_get_global_queue(0, 0), ^{ [self write]; }); } } - (void)read { dispatch_async(_queue, ^{ sleep(1); NSLog(@"read..."); }); } - (void)write { dispatch_barrier_async(_queue, ^{ sleep(1); NSLog(@"write..."); }); } @end |
执行结果:
2018-11-28 14:58:53.655607+0800 MultiThread[11850:2327033] read... 2018-11-28 14:58:53.655634+0800 MultiThread[11850:2327049] read... 2018-11-28 14:58:54.658272+0800 MultiThread[11850:2327033] write... 2018-11-28 14:58:55.662524+0800 MultiThread[11850:2327033] write... 2018-11-28 14:58:56.664781+0800 MultiThread[11850:2327033] read... 2018-11-28 14:58:56.664781+0800 MultiThread[11850:2327035] read... 2018-11-28 14:58:56.664781+0800 MultiThread[11850:2327049] read... 2018-11-28 14:58:57.669830+0800 MultiThread[11850:2327049] write... 2018-11-28 14:58:58.674269+0800 MultiThread[11850:2327049] write... 2018-11-28 14:58:59.678279+0800 MultiThread[11850:2327049] write... 2018-11-28 14:59:00.682485+0800 MultiThread[11850:2327049] read... 2018-11-28 14:59:01.687585+0800 MultiThread[11850:2327049] write... 2018-11-28 14:59:02.693012+0800 MultiThread[11850:2327049] read... 2018-11-28 14:59:03.697764+0800 MultiThread[11850:2327049] write... 2018-11-28 14:59:04.702663+0800 MultiThread[11850:2327049] read... 2018-11-28 14:59:05.705765+0800 MultiThread[11850:2327049] write... 2018-11-28 14:59:06.709361+0800 MultiThread[11850:2327049] read... 2018-11-28 14:59:07.710608+0800 MultiThread[11850:2327049] write... 2018-11-28 14:59:08.715003+0800 MultiThread[11850:2327049] read... 2018-11-28 14:59:09.720101+0800 MultiThread[11850:2327049] write... |
3、结论:在打印read…时可以看到多个read连续打印时时间基本上是相同的,但write打印是相隔1秒的;