pthread_cond_wait()的使用方法

/************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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值