atomic & IO操作

atomic

@property (atomic,assign) int age;

意味着这个属性是原子性操作,也就是保证settergetter是线程同步的.

static inline void reallySetProperty(id self, SEL _cmd, id newValue, ptrdiff_t offset, bool atomic, bool copy, bool mutableCopy)
{
    if (offset == 0) {
        object_setClass(self, newValue);
        return;
    }

    id oldValue;
    id *slot = (id*) ((char*)self + offset);

    if (copy) {
        newValue = [newValue copyWithZone:nil];
    } else if (mutableCopy) {
        newValue = [newValue mutableCopyWithZone:nil];
    } else {
        if (*slot == newValue) return;
        newValue = objc_retain(newValue);
    }

    if (!atomic) {
        oldValue = *slot;
        *slot = newValue;
    } else {
        spinlock_t& slotlock = PropertyLocks[slot];
        slotlock.lock();
        oldValue = *slot;
        *slot = newValue;        
        slotlock.unlock();
    }

    objc_release(oldValue);
}

源码上来看如果是atomic,赋值的前后加了自旋锁spinlock

它并不能保证使用属性的过程是线程安全的.

        MyPerson *person = [MyPerson new];
        person.datas = [NSMutableArray new];
        
        //如果这边不加锁,多线程情况下并不能保证线程同步.atomic仅保证了getter方法的线程同步.addObject方法不是线程同步
        //加锁
        [person.datas addObject:@"1"];
        [person.datas addObject:@"2"];
        [person.datas addObject:@"3"];
        //解锁

IO操作

读写安全方案

  • 同一时间.只能有一个线程进行写的操作
  • 同一时间,允许有多个线程进行读的操作
  • 同一时间,不允许既有写的操作又有读的操作

pthread_rwlock:读写锁
dispatch_barrier_async 异步栅栏调用

@interface ViewController ()

@property (nonatomic,assign) pthread_rwlock_t lock;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    pthread_rwlock_init(&_lock, NULL);
    
    dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
    
    for (int i = 0; i < 10; i++) {
        
        dispatch_async(queue, ^{
            [self read];
        });
        
        dispatch_async(queue, ^{
            [self write];
        });
    }
}


- (void)read
{
    pthread_rwlock_rdlock(&_lock);
    sleep(1);
    NSLog(@"%s",__func__);
    
    pthread_rwlock_unlock(&_lock);
}

- (void)write
{
    pthread_rwlock_wrlock(&_lock);
    sleep(1);
    NSLog(@"%s",__func__);
    
    pthread_rwlock_unlock(&_lock);
    
}

@end

dispatch_barrier_sync

  • 这个函数传入的并发队列必须是通过dispatch_queue_create创建的.
  • 如果传入的是个串行or全局的并发队列,效果等同于dispatch_async
    dispatch_queue_t queue2 = dispatch_queue_create("queue2", DISPATCH_QUEUE_CONCURRENT);
    for (int i = 0; i < 50; i++) {
        
        dispatch_async(queue2, ^{
            [self read];
        });
        
        
        dispatch_async(queue2, ^{
            [self read];
        });
        
        
        dispatch_async(queue2, ^{
            [self read];
        });
        
        
        
        dispatch_barrier_sync(queue2, ^{
            [self write];
        });
    }


- (void)read
{
//    pthread_rwlock_rdlock(&_lock);
    sleep(1);
    NSLog(@"%s",__func__);
    
//    pthread_rwlock_unlock(&_lock);
}

- (void)write
{
//    pthread_rwlock_wrlock(&_lock);
    sleep(1);
    NSLog(@"%s",__func__);
    
//    pthread_rwlock_unlock(&_lock);
    
}

你可能感兴趣的:(atomic & IO操作)