多个线程访问共享资源
比如两个线程都会把计算结果写到一个整型数中。为了防止,需要一种互斥机制来访问共享资源
互斥锁
同一时刻只能有一个线程访问某个资源。某线程要访问某个共享资源先获得共享资源的互斥锁,完成操作再释放这个互斥锁,然后其它线程就能访问这个共享资源。
还有需要解决无序执行问题,这时就需要引入内存屏障。
在Objective-C中如果属性声明为atomic就能够支持互斥锁,但是因为加解锁会有性能代价,所以一般是声明noatomic的。
死锁
当多个线程在相互等待对方锁结束时就会发生死锁,程序可能会卡住。
void swap(A, B)
{
lock(lockA);
lock(lockB);
int a = A;
int b = B;
A = b;
B = a;
unlock(lockB);
unlock(lockA);
}
//一般没问题,但是如果两个线程使用相反的值同时调用上面这个方法就可能会死锁。线程1获得X的一个锁,线程2获得Y的一个锁,它们会同时等待另一个锁的释放,但是却是没法等到的。
swap(X, Y); // 线程 1
swap(Y, X); // 线程 2
为了防止死锁,需要使用比简单读写锁更好的办法,比如write preference 或read-copy-update算法
优先级反转
运行时低优先级任务由于先取得了释放了锁的共享资源而阻塞了高优先级任务,这种情况叫做优先级反转
最佳安全实践避免问题的方法
从主线程中取到数据,利用一个操作队列在后台处理数据,完后返回后台队列中得到的数据到主队列中。这样的操作不会有任何锁操作。
并发测试
使用SenTestingKit框架测试:https://github.com/nxtbgthng/SenTestingKitAsync
kiwi:https://github.com/allending/Kiwi
GHunit:https://github.com/gabriel/gh-unit/
网友评论