1.互斥量
静态分配互斥量初始化:(1)设置为常量PTHREAD_MUTEX_INITIALIZER;(2)调用pthread_mutex_init初始化;
动态分配互斥量初始化:调用pthread_mutex_init进行初始化。注意:释放内存前必须调用pthread_mutex_destroy.
int pthread_mutex_init(pthread_mutex_t *restrict mutex, const pthread_mutexattr_t *restrict attr);
int pthread_mutex_destroy(pthread_mutex_t *mutex);
互斥量加锁:
int pthread_mutex_lock(pthread_mutex_t *mutex);
互斥量解锁:
int pthread_mutex_unlock(pthread_mutex_t *mutex);
尝试加锁:
int pthread_mutex_trylock(pthread_mutex_t *mutex);
尝试加锁时,若互斥量未被锁住,那么pthread_mutex_trylock将锁住互斥量,不会出现阻塞并返回0;若互斥量已被锁住,则不能对互斥量加锁,而返回EBUSY。
避免死锁:
当线程试图对同一互斥量加锁两次,则死锁。
当一个线程试图以与另一个线程相异的顺序锁住互斥量时,可能导致死锁。
2.读写锁
适用于对数据结构读的次数远大于写的情况下。
读写锁初始化:
int pthread_rwlock_init(pthread_rwlock_t *restrict rwlock, const pthread_rwlockattr_t *restrict attr);
释放锁占用的资源前,需要进行清理:
int pthread_rwlock_destroy(pthread_rwlock_t *rwlock);
读模式加锁:(有必要进行返回值的检查,共享模式下可获取的锁的数量通常有上限)
int pthread_rwlock_rdlock(pthread_rwlock_t *rwlock);
写模式加锁:
int pthread_rwlock_wrlock(pthread_rwlock_t *rwlock);
解锁:
int pthread_rwlock_unlock(pthread_rwlock_t *rwlock);
有条件的加锁:
int pthread_rwlock_tryrdlock(pthread_rwlock_t *rwlock);
int pthread_rwlock_trywrlock(pthread_rwlock_t *rwlock);
3.条件变量
条件变量与互斥量一起使用时,允许线程以无竞争的方式等待待定的条件发生。
条件本身由互斥量保护。线程在改变条件状态前必须首先锁住互斥量,其他线程在获得互斥量之前不会觉察到这种改变,因为必须锁定互斥量以后才能计算条件。
条件变量初始化:
(1)静态初始化,直接赋值PTHREAD_COND_INITIALIZER;或者调用pthread_cond_init赋值;
(2)动态赋值,调用pthread_cond_init赋值.
条件变量所存放的内存空间被释放前,需调用pthread_cond_destroy去初始化。
int pthread_cond_init(pthread_cond_t *restrict cond, pthread_condattr_t *restrict attr);
int pthread_cond_destroy(pthread_cond_t *cond);
等待条件变为真:
int pthread_cond_wait(pthread_cond_t *restrict cond, pthread_mutex_t *restrict mutex);
int pthread_cond_timewait(pthread_cond_t *restrict cond, pthread_mutex_t *restrict mutex, const struct timespec *restrict timeout);
传递给pthread_cond_wait的互斥量是被锁住的,其对条件进行保护;pthread_cond_wait返回时,互斥量将被再次锁住(期间有一次解锁)。
其中,timeout是绝对时间,不是相对时间。
获取当前绝对时间:
void gettimeofday(struct timeval *restrict ptr);//-_-|||
通知线程条件已满足:
int pthread_cond_signal(pthread_cond_t *cond);
int pthread_cond_broadcast(pthread_cond_t *cond);
注意要在改变条件状态后,才能给线程发送信号。