加锁与解锁:
#include
int pthread_rwlock_rdlock(pthread_rwlock_t *rwlock);
int pthread_rwlock_wrlock(pthread_rwlock_t *rwlock);
int pthread_rwlock_unlock(pthread_rwlock_t *rwlock);
All return: 0 if OK, error number on failure
对于读者的数量会有限制,因此调用 pthread_rwlock_rdlock时需要检查返回值。
在正确使用的情况下,不需要检查pthread_rwlock_wrlock和pthread_rwlock_unlock的返回值。
条件加锁:
#include
int pthread_rwlock_tryrdlock(pthread_rwlock_t *rwlock);
int pthread_rwlock_trywrlock(pthread_rwlock_t *rwlock);
Both return: 0 if OK, error number on failure
10.什么是条件变量,它有什么作用?
条件变量是线程可用的另外一种同步机制。条件变量给多个线程提供了一个会合的场所。条件变量与互斥量一起使用时,允许线程以无竞争的方式等待特定条件的发生。条件本身是由互斥量保护的。线程在改变状态前必须首先锁住互斥量,其它线程在获得互斥量之前不会觉察到这种变化。
11.如何使用条件变量?
条件变量的类型为pthread_cond_t ,其初始化与销毁的方式与mutex类似,注意静态变量可以通过指定常量PTHREAD_COND_INITIALIZER来进行初始化。
#include
int pthread_cond_init(pthread_cond_t *restrict cond, pthread_condattr_t *restrict attr);
int pthread_cond_destroy(pthread_cond_t *cond);
Both return: 0 if OK, error number on failure
使用pthread_cond_wait来等待条件变成真。
函数定义如下:
以下是代码片段: #include int pthread_cond_wait(pthread_cond_t *restrict cond, pthread_mutex_t *restrict mutex); int pthread_cond_timedwait(pthread_cond_t *restrict cond, pthread_mutex_t *restrict mutex, const struct timespec *restrict timeout); Both return: 0 if OK, error number on failure |
注意,调用成功返回后,线程需要重新计算条件变量,因为其它线程可能已经改变了条件。
有两个函数用于通知线程一个条件已经被满足。pthread_cond_signal函数用来唤醒一个等待条件满足的线程, pthread_cond_broadcast用来唤醒所有等待条件满足的线程。
他们的定义为:
#include
int pthread_cond_signal(pthread_cond_t *cond);
int pthread_cond_broadcast(pthread_cond_t *cond);
Both return: 0 if OK, error number on failure
下面的这段代码实现了类似于生产者消费者模型的程序,生产者通过enqueue_msg将消息放入队列,并发送信号通知给消费者线程。消费者线程被唤醒然后处理消息。
#include
struct msg {
struct msg *m_next;
/* ... more stuff here ... */
};
struct msg *workq;
pthread_cond_t qready = PTHREAD_COND_INITIALIZER;
pthread_mutex_t qlock = PTHREAD_MUTEX_INITIALIZER;
void
process_msg(void)
{
struct msg *mp;
for (;;) {
pthread_mutex_lock(&qlock);
while (workq == NULL)
pthread_cond_wait(&qready, &qlock);
/*get msg from the queue*/
mp = workq;
workq = mp->m_next;
pthread_mutex_unlock(&qlock);
/* now process the message mp */
}
}
void
enqueue_msg(struct msg *mp)
{
pthread_mutex_lock(&qlock);
/*put msg in queue*/
mp->m_next = workq;
workq = mp;
pthread_mutex_unlock(&qlock);
pthread_cond_signal(&qready);
}
在pthread_cond_signal发送消息之前并不需要占用锁,因为一旦线程被唤醒后通过while发现没有要处理的msg存在则会再次陷入睡眠。如果系统不能容忍这种竞争环境,则需要在unlock之前调用cond_signal,但是在多处理器机器上,这样会导致多线程被唤醒然后立即进入阻塞(cond_signal唤醒线程,但由于我们仍占用着锁,所以这些线程又会立即阻塞)。
原文转自:http://blogread.cn/it/article/3344