linux pthread_cond_timedwait() 线程同步

来源:互联网 发布:淘宝店铺不装修可以吗 编辑:程序博客网 时间:2024/06/10 10:15

1  线程的等待与通知

线程的异步通知机制。一个线程正在等待某件事件的发生(在阻塞),另外一个线程触发一个信号,通知这个线程继续往下运行。请参考如下的程序段,

#include <pthread.h>#include <stdlib.h>#include <unistd.h>#include <errno.h>#include <sys/time.h>#include <stdio.h>#include <limits.h>  //PTHREAD_STACK_MIN/** * @brief gettimeofday() 函数封装一下,主要是怕这个函数不是线程安全 */pthread_mutex_t pGetTime = PTHREAD_MUTEX_INITIALIZER;void gettimeofdayHaxMutex(struct timeval *tv)    //主要担心 gettimeofday 并不是线程安全的函数{    pthread_mutex_lock(&pGetTime);    gettimeofday(tv,NULL);    pthread_mutex_unlock(&pGetTime);}pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;pthread_cond_t cond = PTHREAD_COND_INITIALIZER;#if 0pthread_mutex_init(&mutex,NULL);pthread_cond_init(&cond,NULL);#endifint timedwait_pthread_run(){    int iReturnCode = 0;    pthread_mutex_lock(&mutex);    struct timespec tsp;     //线程睡眠那么长时间,如果有事件,则唤醒这个线程,返回消息    struct timeval now;    gettimeofdayHaxMutex(&now);    tsp.tv_sec = now.tv_sec;    tsp.tv_nsec = now.tv_usec*1000;    //nannoseconds    tsp.tv_sec += 10;   //10秒    iReturnCode = pthread_cond_timedwait(&cond,&mutex,&tsp);    pthread_mutex_unlock(&mutex);    if ( iReturnCode == ETIMEDOUT )    {        fprintf(stderr,"%s","pthread_cond_timedwait timeout!!\n");        return -1;    }    else if ( (iReturnCode == EINVAL) || (iReturnCode == EINVAL) )    {        fprintf(stderr,"%s","pthread_cond_timedwait error!!\n");        return -1;    }    fprintf(stderr,"%s","pthread_cond_timedwait has been signal!!\n");    return 0;}void pthread_signal_run(){    pthread_mutex_lock(&mutex);    pthread_cond_signal(&cond);  //send a signal to wait up the pthread_cond_timedwait() thread    pthread_mutex_unlock(&mutex);}#define MICHAEL_SET_PTHREAD_STACK_SIZE 64int main(){    pthread_attr_t attr;    pthread_attr_init(&attr);    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);   //分离属性    size_t stacksize = MICHAEL_SET_PTHREAD_STACK_SIZE*PTHREAD_STACK_MIN;    pthread_attr_setstacksize(&attr,stacksize);   //线程堆栈大小 512K    pthread_t pWaitPthread;    pthread_t pSignalPhread;    pthread_create(&pWaitPthread,&attr,(void *)timedwait_pthread_run,NULL);    sleep(5);    //sleep(10);    pthread_create(&pSignalPhread,&attr,(void *)pthread_signal_run,NULL);    pthread_attr_destroy(&attr);    while(1)    {        sleep(10);    }    return 0;}

int timedwait_pthread_run()  线程阻塞等待在 pthread_cond_timedwait() 这个函数,等待 cond 条件变量的signal 的到来,如果到指定时间还没有等到信号,则超时返回。这个函数具体使用方法请参考 <<Advanced Programming in the Unix Environment>>。

void pthread_signal_run() 线程函数发送一个信号,正等待在 cond 条件变量的线程得到这个信号后,继续往下运行。


2 需要注意问题

  • 一个 mutex 对应多个 cond 是可以的,因为pthread_cond_wait()  这个函数调用,第一步就是 对mutex解锁。但是,使用多个 mutex 对应一个 cond,行为未定义。  详情请参考 <<Using the linux pthread>> 这本书。
  • 多个线程同时等在一个 cond 条件变量上时,可用 pthread_cond_broadcast()  唤醒所有阻塞在这个条件变量的线程
  • 使用 pthread_create() 创建一个线程,默认属性为非分离,非绑定,默认的线程堆栈为 10M,与父进程同样的优先级。
    pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED) 函数设置线程的分离属性,线程退出时,由系统回收资源。

3 参考书籍

<<Advanced Linux Programming>>   比 <<Advanced Programming in the Unix Environment>>  基础一点

<<Advanced Programming in the Unix Environment>>    简称APUE


0 0