iOS之线程锁NSLock

在多线程操作中,为了保证多线程安全,可以使用NSLock类使多个线程间互斥地使用全局变量等共享资源。NSLock类的实例就是可以调整多线程行为的信号量或互斥型信号量。在Cocoa环境中叫锁。

加锁和解锁的方法都声明在NSLocking协议中。

1
2
3
4
5
-(void)lock;
/*如果锁正在被使用,则线程进入休眠状态。*/
/*如果锁没有被使用,则将锁的状态变为正被使用,线程继续执行。*/
-(void)unlock;

[lockObj lock];[lockObj unlock];之间的代码称为临界区。如果锁正在被使用,则等待该锁资源(等待执行临界区代码)的线程则进入休眠状态;将锁置为没有在被使用时,如果有等待该锁资源的正在休眠的线程,则将其唤醒。

加锁的意思

假设有两个线程a和b,a、b两个线程并行执行,且都需要访问临界区代码,如果b在访问临界区时,a正在访问(此时锁正在被a使用,临界区被上锁),则b会被阻塞(休眠状态),待a执行完临界区unlock之后,b被唤醒然后继续执行。

加锁示例
  1. 加锁失败的例子:

    1
    2
    3
    4
    5
    6
    7
    -(int)lock
    {
    [countLock lock];
    ++theCount;
    [countLock unlock];
    return theCount;/*在解锁后return前,theCount可能还是会被其他线程修改。*/
    }
  2. 正确示例

    1
    2
    3
    4
    5
    6
    7
    8
    -(int)lock
    {
    int tmp;
    [countLock lock];
    tmp = ++theCount;
    [countLock unlock];
    return theCount;/*自动变量tmp可以在整个线程中局部利用,无需担心会被其他线程访问。*/
    }