Atmotic
atomic 只能保证set和get方法内线程安全,比如objc.arry 点语法是安全的,但是[objc.array addObject:someOne]是不安全的。非常耗性能,一般只在Mac上使用。
atomic在源码中相关部分。
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);
}
id objc_getProperty(id self, SEL _cmd, ptrdiff_t offset, BOOL atomic) {
if (offset == 0) {
return object_getClass(self);
}
// Retain release world
id *slot = (id*) ((char*)self + offset);
if (!atomic) return *slot;
// Atomic retain release world
spinlock_t& slotlock = PropertyLocks[slot];
slotlock.lock();
id value = objc_retain(*slot);
slotlock.unlock();
// for performance, we (safely) issue the autorelease OUTSIDE of the spinlock.
return objc_autoreleaseReturnValue(value);
}
IO操作,文件操作(读取,写入)
传统意义上的锁无法满足文件读写的需求,因为读取需要很多个线程可以同时进行,而写入只能有一个线程,但是如果只给写入文件的操作加锁的话,线程又不安全。
pthread_rwlock_t 就满足了我们的需求。
pthread_rwlock_t lock;
pthread_rwlock_init(&_lock,NULL);//初始化
//pthread_rw_tryrdlock(&lock);读_尝试加锁
//pthread_rwlock_trywrlock(&lock);写尝试加锁
//pthread_rwlock_destroy(&lock)// 销毁锁
//读取文件的锁,当有文件在写入时,必须等待写入文件完成
pthread_rwlock_rdlock(&_lock);//读加锁
NSLog(@"%s", __func__);
pthread_rwlock_unlock(&_lock);
//写入文件加锁,无需等待读取文件的操作
pthread_rwlock_wrlock(&_lock);//写加锁
NSLog(@"%s", __func__);
pthread_rwlock_unlock(&_lock);//解锁
dispatch_barrier_async
使用dispatch_barrier_async同样可以解决读写问题,dispatch_barrier_async可以保证在一个队列里,当执行dispatch_barrier_async里面的任务时,其他任务都会停止。实现多读单写需求。
- (void)barrierAsync_rwTest
{
_queue = dispatch_queue_create("rwQueue", DISPATCH_QUEUE_CONCURRENT);
for (int i = 0; i<5; i++) {
[[[NSThread alloc]initWithTarget:self selector:@selector(barrier_read) object:nil]start];
[[[NSThread alloc]initWithTarget:self selector:@selector(barrier_write) object:nil]start];
}
}
- (void)barrier_read{
dispatch_async(_queue, ^{
NSLog(@"%s",__func__);
});
}
- (void)barrier_write{
//必须保证是自己创建的b并发队列
//一旦开始写,队列里的其他任务都不能进行
dispatch_barrier_async(_queue, ^{
NSLog(@"%s",__func__);
});
}