iOS底层分析-锁(二)
2024-02-12 23:59:11
synchronized中SyncData的结构
我们先来看一下SyncData,它的结构如下:
struct SyncData {
pthread_mutex_t mutex;
long spinlock;
struct pthread_cond cond;
};
- mutex:这是一个pthread_mutex_t类型的变量,它是一个互斥锁。
- spinlock:这是一个long类型的变量,它是一个自旋锁。
- cond:这是一个pthread_cond_t类型的变量,它是一个条件变量。
mutex
mutex是一个互斥锁,它可以保证只有一个线程可以同时访问临界区。当一个线程进入临界区时,它会获得互斥锁,其他线程将被阻塞,直到该线程释放互斥锁。
spinlock
spinlock是一个自旋锁,它与互斥锁类似,但它不会阻塞线程。当一个线程试图获取自旋锁时,如果自旋锁已经被另一个线程持有,它将自旋等待,直到自旋锁被释放。
cond
cond是一个条件变量,它可以用来通知线程某个条件已经满足。当一个线程等待某个条件满足时,它可以调用pthread_cond_wait()函数,该函数将使线程进入睡眠状态,直到条件满足。当另一个线程调用pthread_cond_signal()函数时,它将唤醒所有正在等待该条件的线程。
SyncData的用法
SyncData结构用于实现synchronized。当一个线程进入synchronized块时,它会先获取SyncData结构中的互斥锁,然后才能访问临界区。当线程离开synchronized块时,它会释放互斥锁。
如果一个线程试图获取SyncData结构中的互斥锁,但互斥锁已经被另一个线程持有,它将自旋等待,直到互斥锁被释放。
如果一个线程在等待SyncData结构中的条件变量时,另一个线程调用了pthread_cond_signal()函数,那么该线程将被唤醒。
示例代码
@synchronized(self) {
// 临界区代码
}
上面的代码是一个synchronized块,它使用self作为锁对象。当一个线程进入synchronized块时,它会先获取self对象的互斥锁,然后才能访问临界区。当线程离开synchronized块时,它会释放互斥锁。
如果一个线程试图获取self对象的互斥锁,但互斥锁已经被另一个线程持有,它将自旋等待,直到互斥锁被释放。
如果一个线程在等待self对象的条件变量时,另一个线程调用了pthread_cond_signal()函数,那么该线程将被唤醒。
总结
SyncData结构用于实现synchronized关键字。它包含一个互斥锁、一个自旋锁和一个条件变量。互斥锁用于保证只有一个线程可以同时访问临界区。自旋锁用于减少线程在等待互斥锁时的时间开销。条件变量用于通知线程某个条件已经满足。