/************pthread_cond_wait()的使用方法**********/
pthread_mutex_lock(&qlock);
pthread_cond_wait(&qready, &qlock);
pthread_mutex_unlock(&qlock);
/*****************************************************/
The mutex passed to pthread_cond_wait protects the condition.The caller
passes it locked to the function, which then atomically places the
calling thread on the list of threads waiting for the condition and
unlocks the mutex. This closes the window between the time that the
condition is checked and the time that the thread goes to sleep waiting
for the condition to change, so that the thread doesn't miss a change
in the condition. When pthread_cond_wait returns, the mutex is again
locked.
上面是APUE的原话,就是说pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t
*mutex)函数传入的参数mutex用于保护条件,因为我们在调用pthread_cond_wait时,如果条件不成立我们就进入阻塞,但是进入阻
塞这个期间,如果条件变量改变了的话,那我们就漏掉了这个条件。因为这个线程还没有放到等待队列上,所以调用pthread_cond_wait前要先锁
互斥量,即调用pthread_mutex_lock(),pthread_cond_wait在把线程放进阻塞队列后,自动对mutex进行解锁,使得
其它线程可以获得加锁的权利。这样其它线程才能对临界资源进行访问并在适当的时候唤醒这个阻塞的进程。当pthread_cond_wait返回的时候又自动给mutex加锁。
实际上边代码的加解锁过程如下:
/************pthread_cond_wait()的使用方法**********/
pthread_mutex_lock(&qlock); /*lock*/
pthread_cond_wait(&qready, &qlock); /*block-->unlock-->wait() return-->lock*/
pthread_mutex_unlock(&qlock); /*unlock*/
/*****************************************************/
请看下面代码和在FC9运行结果:
#include <stdlib.h>
#include <pthread.h>
#include <stdio.h>
struct msg {
struct msg *next;
int num;
};
struct msg *head;
pthread_cond_t has_product = PTHREAD_COND_INITIALIZER;
pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
void *consumer(void *p)
{
struct msg *mp;
for (;;)
{
pthread_mutex_lock(&lock);
printf("Consume pthread_mutex_lock/n");
while (head == NULL)
pthread_cond_wait(&has_product, &lock);
printf("Consume pthread_cond_wait/n");
mp = head;
head = mp->next;
pthread_mutex_unlock(&lock);
printf("Consume pthread_mutex_unlock/n");
printf("Consume %d/n", mp->num);
free(mp);
sleep(rand() % 5);
}
}
void *producer(void *p)
{
struct msg *mp;
for (;;) {
mp = malloc(sizeof(struct msg));
mp->num = rand() % 1000 + 1;
printf("Produce %d/n", mp->num);
pthread_mutex_lock(&lock);
printf("Produce pthread_mutex_lock/n");
mp->next = head;
head = mp;
pthread_mutex_unlock(&lock);
printf("Produce pthread_mutex_unlock/n");
pthread_cond_signal(&has_product);
printf("Produce pthread_cond_signal/n");
sleep(rand() % 5);
}
}
int main(int argc, char *argv[])
{
pthread_t pid, cid;
srand(time(NULL));
pthread_create(&pid, NULL, producer, NULL);
pthread_create(&cid, NULL, consumer, NULL);
pthread_join(pid, NULL);
pthread_join(cid, NULL);
return 0;
}
编译: gcc -o cond -lpthread cond.c
运行: [root@dep4 test]# ./cond
Produce 198
Produce pthread_mutex_lock
Produce pthread_mutex_unlock
Produce pthread_cond_signal
Produce 753
Produce pthread_mutex_lock
Produce pthread_mutex_unlock
Produce pthread_cond_signal
Consume pthread_mutex_lock
Consume pthread_cond_wait
Consume pthread_mutex_unlock
Consume 753
Consume pthread_mutex_lock
Consume pthread_cond_wait
Consume pthread_mutex_unlock
Consume 198
Produce 69
Produce pthread_mutex_lock
Produce pthread_mutex_unlock
Produce pthread_cond_signal
Consume pthread_mutex_lock
Consume pthread_cond_wait
Consume pthread_mutex_unlock
Consume 69
Produce 934
Produce pthread_mutex_lock
Produce pthread_mutex_unlock
Produce pthread_cond_signal
Consume pthread_mutex_lock
Consume pthread_cond_wait
Consume pthread_mutex_unlock
Consume 934
Produce 598
Produce pthread_mutex_lock
Produce pthread_mutex_unlock
Produce pthread_cond_signal
Consume pthread_mutex_lock
Consume pthread_cond_wait
Consume pthread_mutex_unlock
Consume 598
Consume pthread_mutex_lock //consume线程获取互斥量lock
Produce 601
Produce pthread_mutex_lock //为何重复能获得互斥量?
Produce pthread_mutex_unlock
Produce pthread_cond_signal
Consume pthread_cond_wait
Consume pthread_mutex_unlock
Consume 601
Consume pthread_mutex_lock
Produce 159
Produce pthread_mutex_lock
Produce pthread_mutex_unlock
Produce pthread_cond_signal
Consume pthread_cond_wait
Consume pthread_mutex_unlock
Consume 159
Consume pthread_mutex_lock
问题: 上述红色部分:为何重复能获得互斥量?
解答: 下红色部分
[root@dep4 test]# man pthread_cond_wait
PTHREAD_COND_TIMEDWAIT(P) POSIX Programmer¡¯s Manual PTHREAD_COND_TIMEDWAIT(P)
NAME
pthread_cond_timedwait, pthread_cond_wait - wait on a condition
SYNOPSIS
#include <pthread.h>
int pthread_cond_timedwait(pthread_cond_t *restrict cond,
pthread_mutex_t *restrict mutex,
const struct timespec *restrict abstime);
int pthread_cond_wait(pthread_cond_t *restrict cond,
pthread_mutex_t *restrict mutex);
DESCRIPTION
The pthread_cond_timedwait() and pthread_cond_wait() functions shall block on a
condition variable. They shall be called with mutex locked by the calling thread
or undefined behavior results.
These functions atomically release mutex and cause the calling thread to block on
the condition variable cond; atomically here means "atomically with respect to
access by another thread to the mutex and then the condition variable". That is,
if another thread is able to acquire the mutex after the about-to-block thread has
released it, then a subsequent call to pthread_cond_broadcast() or
pthread_cond_signal() in that thread shall behave as if it were issued after the
about-to-block thread has blocked.
Upon successful return, the mutex shall have been locked and shall be owned by the
calling thread.
When using condition variables there is always a Boolean predicate involving
shared variables associated with each condition wait that is true if the thread
pthread_cond_wait()的使用方法
最新推荐文章于 2022-10-19 07:10:36 发布