pthread_cond 应用

来源:互联网 发布:同城交友源码带数据 编辑:程序博客网 时间:2024/06/03 20:41

一、家庭成员:

pthread_cond_t cond = PTHREAD_COND_INITIALIZER;

int pthread_cond_init(pthread_cond_t *cond,pthread_condattr_t *cond_attr);

int pthread_cond_signal(pthread_cond_t *cond);

int pthread_cond_broadcast(pthread_cond_t *cond);

int pthread_cond_wait(pthread_cond_t *cond,pthread_mutex_t *mutex);

int pthread_cond_timedwait(pthread_cond_t *cond,pthread_mutex_t *mutex, const struct timespec*abstime);

int pthread_cond_destroy(pthread_cond_t *cond);


二、成员功能:

pthread_cond_init initializes the condition variable cond,using the condition attributes specified incond_attr, ordefault attributes ifcond_attr is NULL.

Variables of type pthread_cond_t can also be initializedstatically, using the constantPTHREAD_COND_INITIALIZER. InthePthreads-w32 implementation, an application should stillcallpthread_cond_destroy at some point to ensure that anyresources consumed by the condition variable are released.

pthread_cond_signal restarts one of the threads that arewaiting on the condition variablecond. If no threads arewaiting oncond, nothing happens. If several threads arewaiting oncond, exactly one is restarted, but it is notspecified which.

pthread_cond_broadcast restarts all the threads that arewaiting on the condition variablecond. Nothing happens if nothreads are waiting oncond.

pthread_cond_wait atomically unlocks the mutex (asperpthread_unlock_mutex) and waits for the condition variablecond to be signalled. The thread execution is suspended anddoes not consume any CPU time until the condition variable issignalled. Themutex must be locked by the calling thread onentrance topthread_cond_wait. Before returning to the callingthread,pthread_cond_wait re-acquiresmutex (as perpthread_lock_mutex).

Unlocking the mutex and suspending on the condition variable isdone atomically. Thus, if all threads always acquire the mutex beforesignalling the condition, this guarantees that the condition cannotbe signalled (and thus ignored) between the time a thread locks themutex and the time it waits on the condition variable.

pthread_cond_timedwait atomically unlocks mutex andwaits oncond, aspthread_cond_wait does, but it alsobounds the duration of the wait. Ifcond has not beensignalled within the amount of time specified byabstime, themutexmutex is re-acquired and pthread_cond_timedwaitreturns the errorETIMEDOUT. Theabstime parameterspecifies an absolute time, with the same origin astime(2)andgettimeofday(2).

pthread_cond_destroy destroys a condition variable, freeingthe resources it might hold. No threads must be waiting on thecondition variable on entrance topthread_cond_destroy.

三、功能详解:

1.pthread_cond_wait:

/************pthread_cond_wait()的正确使用方法**********/
pthread_mutex_lock(&qlock);    /*lock*/
pthread_cond_wait(&qready, &qlock); /*block-->unlock-->wait() return-->lock*/
pthread_mutex_unlock(&qlock); /*unlock*/
/*****************************************************/
如何体现pthread_cond_wait(&qready, &qlock); /*block-->unlock-->wait() return-->lock*/???

下面用例子说明,假如去掉pthread_mutex_lock,单独使用pthread_cond_wait。


代码例子:

#include "stdio.h"
#include "unistd.h"
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;

int n = 0;
void * fun_thread1()
{
        while(1)
        {
                pthread_cond_wait(&cond,&mutex);
                printf("1111111 receive a pthread_cond_signal\n");
                printf("n = %d\n",n);
                sleep(5);
                //pthread_mutex_unlock(&mutex);
                n++;
                printf("n = %d \n",n);

                sleep(5);
        }

}

void * fun_thread2()
{
        while(1)
        {
                pthread_cond_wait(&cond,&mutex);
                printf("2222222 receive a pthread_cond_signal\n");
                printf("n = %d\n",n++);
                sleep(2);
        }

}
void * fun_thread3()
{
        while(1)
        {
                pthread_cond_signal(&cond);
                sleep(1);
        }
}

int main()
{
        pthread_t a,b,c;

        pthread_create(&a,NULL,fun_thread1,NULL);
        pthread_create(&b,NULL,fun_thread2,NULL);
        pthread_create(&c,NULL,fun_thread3,NULL);
        while(1);
        return 0;
}

结果显示:

[elbort@elbort test1]$ ./test
1111111 receive a pthread_cond_signal
n = 0

//中间等待了5秒
n = 1 

//中间等待了5秒
2222222 receive a pthread_cond_signal
n = 1

//中间等待了2秒

1111111 receive a pthread_cond_signal
n = 2
n = 3
2222222 receive a pthread_cond_signal
n = 3

结果分析:首先线程1运行(可能会是线程2先运行,这个不能确定),打印了第一个n值,然后sleep5秒。但是期间线程2还是处于等待过程中,按照block-->unlock-->wait() return-->lock的过程来分析,线程2接收到signal后,解除了block,unlock(本来没有,就什么事也没发生),wait等待有效空闲的mutex但是此时的mutex被线程1锁住了,它只能等待。直到线程1运行完下面的内容:打印第二个n值,sleep5秒,重新进入pthread_cond_wait,也执行block-->unlock-->wait() return-->lock的过程,来到unlock,这时mutex被释放,线程2赶紧lock住mutex,这时线程1就像线程2之前那样等待mutex的解锁空闲状态。

同样采用上面的代码,只是修改其中一句,去掉//pthread_mutex_unlock(&mutex);的注释,得出的结果为:

[elbort@elbort test1]$ gcc -Wall -lpthread -o test test.c
[elbort@elbort test1]$ ./test
1111111 receive a pthread_cond_signal
n = 0
n = 1
2222222 receive a pthread_cond_signal
n = 1
2222222 receive a pthread_cond_signal
n = 2
2222222 receive a pthread_cond_signal
n = 3
1111111 receive a pthread_cond_signal
n = 4

线程1,2输出顺序变乱,线程2在线程1还没运行到最后就开始运行了。


正常使用pthread_cond_wait 例子:

例子代码:

#include <stdio.h>
#include <pthread.h>
#include "unistd.h"
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
int condition = 0;
int count = 0;

int consume( void )
{
   while( 1 )
   {
      pthread_mutex_lock( &mutex );
      printf("Consume lock the mutex\n");
      while( condition == 0 )
      {
         printf("Consume enter the pthread_cond_wait,release the mutex\n");
         pthread_cond_wait( &cond, &mutex );
         printf("Consume leave the pthread_cond_wait,lock the mutex\n");
      }
      printf("Consume %d\n",count);
      condition = 0;
      pthread_cond_signal( &cond );
      printf("Consume release the mutex\n");
      sleep(5);
      pthread_mutex_unlock( &mutex );
      sleep(1);
   }

   return( 0 );
}

void*  produce( void * arg )
{
   while( 1 )
   {
      pthread_mutex_lock( &mutex );
      printf("*******produce lock the mutex\n");
      while( condition == 1 )
      {
         printf("*******Product enter the pthread_cond_wait,release the mutex\n");
         pthread_cond_wait( &cond, &mutex );
         printf("*******Product leave the pthread_cond_wait,lock the mutex\n");
      }
      count++;
      printf( "*******Produced %d\n", count );
      condition = 1;
      pthread_cond_signal( &cond );
      printf("*******produce release the mutex\n");
      sleep(5);
      pthread_mutex_unlock( &mutex );
                                                                                                                                                         
   }
   return( 0 );
}

int main( void )
{
   pthread_t thread;
   pthread_create( &thread, NULL, &produce, NULL );
   return consume();
}
                                                                                                                                                              

结果显示:

[elbort@elbort test1]$ gcc -Wall -lpthread -o test new.c
[elbort@elbort test1]$ ./test
Consume lock the mutex
Consume enter the pthread_cond_wait,release the mutex
*******produce lock the mutex
*******Produced 1
*******produce release the mutex
*******produce lock the mutex
*******Product enter the pthread_cond_wait,release the mutex
Consume leave the pthread_cond_wait,lock the mutex
Consume 1
Consume release the mutex
*******Product leave the pthread_cond_wait,lock the mutex
*******Produced 2
*******produce release the mutex
*******produce lock the mutex
*******Product enter the pthread_cond_wait,release the mutex
Consume lock the mutex
Consume 2
Consume release the mutex
*******Product leave the pthread_cond_wait,lock the mutex
*******Produced 3
*******produce release the mutex
*******produce lock the mutex
*******Product enter the pthread_cond_wait,release the mutex


---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------



2.pthread_cond_timedwait:

注意:设置超时时间是用相对时间,相对于1970年1月1日0时0分到现在所经过的秒数。

简单应用,代码说明:

#include <pthread.h>
#include "stdio.h"
#include "sys/time.h"
#include "unistd.h"
#include "stdlib.h"
#include "errno.h"
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;

void *fun_thread()
{
        int ret;
        struct timespec timeout;
        while(1)
        {
                timeout.tv_sec =time(NULL)+8;        //注意每次调用timedwait都需要重新给时间进行赋值
                timeout.tv_nsec = 0;
                pthread_mutex_lock(&mutex);
                ret = pthread_cond_timedwait(&cond,&mutex,&timeout);   //timedwait工作原理和wait大致相同,只是前者比后者多了时间判断,如果超时就相当于接收到siagnal,返回值为ETIMEDOUT
                if(ret == ETIMEDOUT)
                {
                        printf("Time out of the pthread_cond_timedwait\n");
                }
                else
                printf("pthread_cond_timedwait receive the signal without time out\n");
                pthread_mutex_unlock(&mutex);
        }
        return NULL;

}


int main()
{
        pthread_t thread;
        pthread_create(&thread,NULL,fun_thread,NULL);
        while(1)
        {
                sleep(5);
                pthread_cond_signal(&cond);
        }
        printf("End of main\n");
        return 0;
}



结果显示:

[elbort@elbort test1]$ gcc -Wall -lpthread -o test test1.c
[elbort@elbort test1]$ ./test
pthread_cond_timedwait receive the signal without time out
pthread_cond_timedwait receive the signal without time out
pthread_cond_timedwait receive the signal without time out
pthread_cond_timedwait receive the signal without time out


如果将sleep(5);改成sleep(10);结果显示如下:

[elbort@elbort test1]$ gcc -Wall -lpthread -o test test1.c
[elbort@elbort test1]$ ./test
Time out of the pthread_cond_timedwait
pthread_cond_timedwait receive the signal without time out
Time out of the pthread_cond_timedwait
pthread_cond_timedwait receive the signal without time out
Time out of the pthread_cond_timedwait
pthread_cond_timedwait receive the signal without time out
Time out of the pthread_cond_timedwait
pthread_cond_timedwait receive the signal without time out