1. 原子操作 (Atomic Operations)

编写多线程代码最重要的一点是:对共享数据的访问要加锁。

Shared data is any data which more than one thread can access.

原子操作(Atomic Operations)满足只有一个线程可以访问Shared data, 同时不需要加锁。

原子操作中的"原子"是不可分割的意思。

OSAtomic是OS X的原子操作库。

2. OSAtomic

OSAtomic函数在OSAtomic.h文件中,路径:/usr/include/libkern/OSAtomic.h

在用户域的代码中也可以使用OSAtomic函数。

#import <libkern/OSAtomic.h>

这些方法分为5类:

  • Integer operations
  • Fundamental operations
  • Spinlocks
  • Queues
  • Memory barriers

整数类型

"Due to the finnicky and low-level nature of atomic operations, there are significant limits on data types

and alignments. Atomic operations are only available for 32-bit and 64-bit data types, and on some

platforms (PowerPC being the only OS X one that I know of) they are only available for 32-bit. Always

use data types with a guaranteed size, such as int32_t, rather than built-in types ilke int. " Ref[1]

地址对齐

"The values must also be aligned to their size. This means that the address of the value has to be

a multiple of the value's size. " Ref[1]

"Alignment should only be a worry if you're messing around with addresses trying to set up your own

packing or using packed structs. And, well, don't use atomic operations with those." Ref[1]

2.1 Integer Operations (整数操作)

x += 1; // 该操作不是原子的

x++; // 也不是原子的

OSAtomicAdd32()

OSAtomicIncrement()

OSAtomicDecrement()

OSAtomicOr() OSAtomicAnd() OSAtomicXor()

2.2 Fundamental Operations (基本操作)

整数操作概念上基于基本的原子操作: compare and swap, 即CAS.

CAS函数接受3个参数:old value, new value, a pointer to a variable.

如果variable的值和old value匹配,则将new value赋值给variable,并返回true.

CAS 如下:

bool CompareAndSwap(int old, int new, int *value)
{
if(*value == old)
{
*value = new;
return true;
}
else
return false;
}

" If the new value is assigned and the function returns true then you can be absolutely certain

that the value transitioned directly from old tonew without any other intermediate value." Ref[1]

OSAtomic提供了OSAtomicCompareAndSwap函数族。

用CAS来实现 OSAtomicAdd32函数:

"First, fetch the original value. Then add to obtain a new value. Finally, use compare and swap

with the original and new values. If it failed, go back and try everything again." Ref[1]

  int32_t OSAtomicAdd32(int32_t howmuch, volatile int32_t *value)
{
bool success;
int32_t new; do {
int32_t orig = *value;
new = orig + howmuch;
success = OSAtomicCompareAndSwap32(orig, new, value);
} while(!success); return new;
}

TODO: 关键字  volatile

OSAtomicCompareAndSwapPtrBarrier()函数的使用:

  

void AddNode(ListNode *node, ListNode * volatile *head)

{

   bool success;

  do {

    ListNode *orig = *head;

    node->next = orig;

    success = OSAtomicCompareAndSwapPtrBarrier(orig, node, (void *)head);

  } while(!success);

}

  

ListNode *StealList(ListNode * volatile *head)
{
bool success;
ListNode *orig;
do {
orig = *head;
success = OSAtomicCompareAndSwapPtrBarrier(orig, NULL, (void *)head);
} while(!success);
return orig;
}

  

"This kind of structure can be really useful in multithreaded programming. Many threads can safely

useAddNode to add new nodes to the structure. A worker thread can then use StealList to grab the

list and process it." Ref[1]

  

ABA Problem (ABA问题)

关于ABA问题参考: TODO  

Ref[1] ABA Problem 这一节中讲解的很明了。

2.3 Spinlocks (自旋锁)

"A spinlock is a primitive type of lock that does not use any OS facilities." Ref[1]

普通锁的概念:

"A lock in general is a facility which provides mutual exclusion between threads.

Two threads attempt to acquire a lock. One succeeds, the other waits. When the first one unlocks the lock,

the second one then acquires it.

Generally, when the second thread is waiting, we want it to be blocked so that it does not take any CPU

time while it's blocked. This requires intervention by the OS to stop the thread, and start it again when unlocking.

This OS intervention comes with a certain amount of overhead that is not always desirable. " Ref[1]

普通锁需要系统OS的介入。

Spinlock的概念:

Spinlock很轻量,完全在用户空间,不需要OS介入。副作用是当线程在waiting时,该线程并不会blocked,

而是不停的检查spinlock直到其unlocked。

"Spinlocks perform very well when a lock is not contended (only one thread at a time is accessing it)

but perform poorly when a lock is contended for an extended period." Ref[1]

TODO: 那么适用spinlock的场景是什么呢?

You should generally use those higher-level (pthread_mutex, NSLock) abstractions, but spin locks are useful when performance

is absolutely critical and contention is rare.

2.4 Queues

"Unfortunately, after some additional investigation, I discovered that OSQueue

is not entirely thread safe and thus should not be used. Since I have no idea if or

when this will be fixed, you should avoid the use of OSQueue."  Ref[1]

TODO: OSQueue的调研

2.5 Memory Barriers (内存屏障,内存围墙)

"Some architectures reorder memory reads and writes for extra speed.

These reorderings are hidden from the program by the CPU, but they are not hidden

from code executing on other CPUs at the same time. This can cause serious problems." Ref[1]

Memory Barries 的作用:

"A memory barrier forces all all reads before the barrier to complete before any

reads after the barrier complete. The same goes for writes. Technically, there can be

separate barriers for reads and writes, but OSAtomic rolls them both into a single concept."

TODO: 使用OSMemoryBarrier 的例子。

3. OSAtomicIncrement64 vs. OSAtomicIncrement64Barrier


Reference

1. Friday Q&A 2011-03-04: A Tour of OSAtomic (AAAAA)

https://www.mikeash.com/pyblog/friday-qa-2011-03-04-a-tour-of-osatomic.html

2.

http://cocoadev.com/OSAtomic

3. 自旋锁spinlock剖析与改进  (未读)

http://kb.cnblogs.com/page/105657/

iOS.Thread.OSAtomic的更多相关文章

  1. iOS多线程之1.从Thread看多线程的生命周期

      Thread 是多线程中最容易理解,但是使用起来又是最麻烦的一种多线程方法.为什么说容易理解呢?一个NSThread的对象就是一条线程.使用起来麻烦是因为,需要我们自己管理线程的生命周期:创建线程 ...

  2. ios基础篇(二十九)—— 多线程(Thread、Cocoa operations和GCD)

    一.进程与线程 1.进程 进程是指在系统中正在运行的一个应用程序,每个进程之间是独立的,每个进程均运行在其专用且受保护的内存空间内: 如果我们把CPU比作一个工厂,那么进程就好比工厂的车间,一个工厂有 ...

  3. iOS 中NSOperationQueue,Grand Central Dispatch , Thread的上下关系和区别

    In OS X v10.6 and later, operation queues use the libdispatch library (also known as Grand Central D ...

  4. iOS 10 的一个重要更新-线程竞态检测工具 Thread Sanitizer

    本文介绍了 Xcode 8 的新出的多线程调试工具 Thread Sanitizer,可以在 app 运行时发现线程竞态. 想想一下,你的 app 已经近乎大功告成:它经过精良的打磨,单元测试全覆盖. ...

  5. iOS开发-多线程编程技术(Thread、Cocoa operations、GCD)

    简介 在软件开发中,多线程编程技术被广泛应用,相信多线程任务对我们来说已经不再陌生了.有了多线程技术,我们可以同做多个事情,而不是一个一个任务地进行.比如:前端和后台作交互.大任务(需要耗费一定的时间 ...

  6. iOS 报错:(子线程中更新UI)This application is modifying the autolayout engine from a background thread after the engine was accessed from the main thread. This can lead to engine corruption and weird crashes.

    今天在写程序的时候,使用Xcode 运行工程时报出下面的错误错信息,我还以为是什么呢,好久没遇到过这样的错误了. **ProjectName[1512:778965] This application ...

  7. iOS多线程之Thread

    多线程 • Thread 是苹果官方提供的,简单已用,可以直接操作线程对象.不过需要程序员自己管理线程的生命周期,主要是创建那部分 优缺点 面向对象,简单易用 直接操作线程对象 需要自己管理线程生命周 ...

  8. Mac&iOS之多线程--转自http://geeklu.com/2012/02/thread/

    http://geeklu.com/2012/02/thread/ 首先循环体的开始需要检测是否有需要处理的事件,如果有则去处理,如果没有则进入睡眠以节省CPU时间. 所以重点便是这个需要处理的事件, ...

  9. iOS 并行编程:Thread

    1 创建线程 1.1 NSThread       使用 NSThread 来创建线程有两个可以使用的方法: 1) 使用 detachNewThreadSelector:toTarget:withOb ...

随机推荐

  1. css样式中的绝对路径的参考对象

    如果div标签中没有position:absolute;样式,那么img的参考对象就是浏览器 如果div标签中有position:absolute;样式,那么img的参考对象就是父元素,即div标签

  2. centos最小安装之后无法使用ifconfig

    Centos7安装之后,无法使用ifconfig(找不到命令) 运行 yum install provides 再安装net-tools即可 yum install net-tools 没有网,下载r ...

  3. linux下mysql升级

    最近漏洞扫描,扫描出了数据库存在中高危漏洞,于是迫切需要进行数据库升级.上网查了各种资料,说法很多,也到自己虚拟机上试了好多方法,终于倒腾出来,做下小总结记录一下. 升级操作: 1.到mysql官网h ...

  4. metasploit framework(十五):弱点扫描

    openvas扫描生成NBE格式的日志 改个比较好记的文件名 将日志导入到msf进行后续操作,导入之前查看一下hosts和services 导入nbe格式的文件 查看漏洞弱点 msf直接调用nessu ...

  5. python模块 re模块与python中运用正则表达式的特点 模块知识详解

    1.re模块和基础方法 2.在python中使用正则表达式的特点和问题 3.使用正则表达式的技巧 4.简单爬虫例子 一.re模块 模块引入; import re 相关知识: 1.查找: (1)find ...

  6. 算法之LOWB三人组之冒泡排序

    排序 冒泡排序(Bubble Sort)时间复杂度为O(n^2) 列表每两个相邻的数,如果前面比后面大,则交换这两个数 一趟排序完成后,则无序区减少一个数,有序区增加一个数. def bubble_s ...

  7. python基础之字符串常用操作总结

    字符串的索引 s = 'ABCDLSESRF' # 索引 这两个很简单没什么说的 s1 = s[0] print(s1) # A s2 = s[2] print(s2) # C 切片 s = 'ABC ...

  8. javascript 表格排序和表头浮动效果(扩展SortTable)

    前段时间一个项目有大量页面用到表格排序和表头浮动的效果,在网上找了几个表格排序的js代码,最后选择了 Stuart Langridge的SortTable,在SortTable基础上做了些扩展,加上了 ...

  9. leetcode 数组类型题总结

    1,removeDuplicates(I) int removeDuplicatesI(vector<int>& nums){ // 重新组织数组,同 removeDuplicat ...

  10. ansible1

    前期工作: 第一步:下载epel源 wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo 第二步: ...