iOS - 原子操纵

打印 上一主题 下一主题

主题 1490|帖子 1490|积分 4470

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

x
在 Objective-C 运行时中,原子操纵主要通过以下几种方式实现:
1. 基本原子操纵

  1. // 原子操作的基本实现
  2. #if __has_feature(c_atomic)
  3. #define OSAtomicIncrement32(p)        __c11_atomic_add((_Atomic(int32_t) *)(p), 1, __ATOMIC_RELAXED)
  4. #define OSAtomicDecrement32(p)        __c11_atomic_sub((_Atomic(int32_t) *)(p), 1, __ATOMIC_RELAXED)
  5. #define OSAtomicIncrement32Barrier(p) __c11_atomic_add((_Atomic(int32_t) *)(p), 1, __ATOMIC_SEQ_CST)
  6. #define OSAtomicDecrement32Barrier(p) __c11_atomic_sub((_Atomic(int32_t) *)(p), 1, __ATOMIC_SEQ_CST)
  7. #else
  8. // 使用内联汇编实现原子操作
  9. static ALWAYS_INLINE int32_t
  10. OSAtomicIncrement32(volatile int32_t *value) {
  11.     return __sync_fetch_and_add(value, 1) + 1;
  12. }
  13. static ALWAYS_INLINE int32_t
  14. OSAtomicDecrement32(volatile int32_t *value) {
  15.     return __sync_fetch_and_sub(value, 1) - 1;
  16. }
  17. #endif
复制代码
2. 自旋锁实现

  1. typedef struct {
  2.     volatile int32_t value;
  3. } OSSpinLock;
  4. // 自旋锁的原子操作
  5. static ALWAYS_INLINE void
  6. OSSpinLockLock(volatile OSSpinLock *lock)
  7. {
  8.     do {
  9.         while (lock->value != 0) {
  10.             // 忙等待
  11.             __asm__ volatile ("pause");
  12.         }
  13.     } while (!OSAtomicCompareAndSwap32(0, 1, &lock->value));
  14. }
  15. static ALWAYS_INLINE bool
  16. OSSpinLockTry(volatile OSSpinLock *lock)
  17. {
  18.     return OSAtomicCompareAndSwap32(0, 1, &lock->value);
  19. }
  20. static ALWAYS_INLINE void
  21. OSSpinLockUnlock(volatile OSSpinLock *lock)
  22. {
  23.     OSAtomicAnd32Barrier(0, &lock->value);
  24. }
复制代码
3. 比较和互换操纵

  1. // 原子比较和交换操作
  2. static ALWAYS_INLINE bool
  3. OSAtomicCompareAndSwapPtr(void *oldp, void *newp, void *volatile *dst)
  4. {
  5.     return __sync_bool_compare_and_swap(dst, oldp, newp);
  6. }
  7. static ALWAYS_INLINE bool
  8. OSAtomicCompareAndSwapLong(long oldl, long newl, volatile long *dst)
  9. {
  10.     return __sync_bool_compare_and_swap(dst, oldl, newl);
  11. }
  12. static ALWAYS_INLINE bool
  13. OSAtomicCompareAndSwap32(int32_t old, int32_t new, volatile int32_t *dst)
  14. {
  15.     return __sync_bool_compare_and_swap(dst, old, new);
  16. }
复制代码
4. 内存屏障

  1. // 内存屏障实现
  2. #define OSMemoryBarrier()  __sync_synchronize()
  3. static ALWAYS_INLINE void
  4. OSMemoryBarrierBeforeUnlock()
  5. {
  6. #if defined(__arm__) || defined(__arm64__)
  7.     OSMemoryBarrier();
  8. #endif
  9. }
复制代码
5. 原子引用计数操纵

  1. inline bool
  2. objc_object::rootTryRetain()
  3. {
  4.     return sidetable_tryRetain() || rootRetain_overflow(true);
  5. }
  6. inline bool
  7. objc_object::sidetable_tryRetain()
  8. {
  9.     SideTable& table = SideTables()[this];
  10.    
  11.     bool result = false;
  12.    
  13.     table.lock();
  14.     RefcountMap::iterator it = table.refcnts.find(this);
  15.     if (it != table.refcnts.end()) {
  16.         RefcountMap::value_type &pair = *it;
  17.         if (pair.second & SIDE_TABLE_RC_PINNED) {
  18.             pair.second += SIDE_TABLE_RC_ONE;
  19.             result = true;
  20.         }
  21.         else if (pair.second & SIDE_TABLE_RC_WEAKLY_REFERENCED) {
  22.             pair.second = SIDE_TABLE_RC_ONE | SIDE_TABLE_RC_WEAKLY_REFERENCED;
  23.             result = true;
  24.         }
  25.     }
  26.     table.unlock();
  27.    
  28.     return result;
  29. }
复制代码
6. 原子属性访问器

  1. // 原子属性的 getter
  2. id objc_getProperty(id self, SEL _cmd, ptrdiff_t offset, BOOL atomic) {
  3.     if (!atomic) return *((id *)((char *)self + offset));
  4.    
  5.     // 原子操作
  6.     spinlock_t& slotlock = PropertyLocks[GOODHASH(offset)];
  7.     slotlock.lock();
  8.     id value = *((id *)((char *)self + offset));
  9.     slotlock.unlock();
  10.     return value;
  11. }
  12. // 原子属性的 setter
  13. static inline void reallySetProperty(id self, SEL _cmd, id newValue,
  14.                                    ptrdiff_t offset, bool atomic, bool copy)
  15. {
  16.     if (!atomic) {
  17.         *((id *)((char *)self + offset)) = newValue;
  18.         return;
  19.     }
  20.    
  21.     spinlock_t& slotlock = PropertyLocks[GOODHASH(offset)];
  22.     slotlock.lock();
  23.     *((id *)((char *)self + offset)) = newValue;
  24.     slotlock.unlock();
  25. }
复制代码
7. 原子操纵的使用场景

1. 引用计数管理
  1. // 原子递增引用计数
  2. id objc_retain(id obj) {
  3.     if (!obj) return obj;
  4.     if (obj->isTaggedPointer()) return obj;
  5.     return obj->retain();
  6. }
复制代码
2. 属性访问
  1. // 原子属性的实现
  2. @property (atomic) NSString *name;
复制代码
3. 数据结构操纵
  1. // 线程安全的数组操作
  2. - (void)addObject:(id)object {
  3.     @synchronized(self) {
  4.         [_array addObject:object];
  5.     }
  6. }
复制代码
这些原子操纵的实现保证了:


  • 原子性:操纵要么完全执行,要么完全不执行


  • 可见性:一个线程的修改对其他线程立即可见


  • 有序性:防止指令重排导致的标题
通过这些机制,Objective-C 运行时可以大概保证多线程情况下的数据一致性和线程安全。


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

梦见你的名字

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表